1. 程式人生 > >Java反射reflect學習 Class.forName()用法詳解

Java反射reflect學習 Class.forName()用法詳解

    恰巧前段時間面試的時候問到了Java的反射,當時答得不是很好,正好抽空重新溫習下,本文只講解下通過反射獲取到類的屬性、構造方法、方法,關於類載入器(ClassLoader)將在其他文章中有具體介紹,本文不作介紹。

Class.forName()用法詳解

主要功能
Class.forName(xxx.xx.xx)返回的是一個類。
Class.forName(xxx.xx.xx)的作用是要求JVM查詢並載入指定的類,也就是說JVM會執行該類的靜態程式碼段。 
A a = (A)Class.forName(“pacage.A”).newInstance();//這和你 A a = new A(); 是一樣的效果。

首先,通過Class獲取類的位元組碼
Class clazz = Class.forName("clazz.Test01");
1、獲取類的屬性
  //獲取類的屬性物件,需要填寫屬性物件的名稱
  Field f1=c.getField("name");//只能獲取public的物件
  Field f2=c.getDeclaredField("age");//可以獲取到private的物件,這很吊吧
  f2.setAccessible(true);//如果屬性是私有的,那麼就需要設定可訪問
2、利用Constructor建立物件
Constructor c = clazz.getConstructor(null);//獲取無參的建構函式
Constructor c = clazz.getConstructor(String.class);//獲取引數為String的建構函式
Constructor c = clazz.getConstructor(String.class, int.class);//獲取引數為String,int的建構函式
Constructor c = clazz.getDeclaredConstructor(List.class);//獲取隱藏為private的建構函式
c.setAccessible(true);//暴力反射
建立物件的另外一種途徑,反射出類的無參建構函式並建立物件
Class clazz = Class.forName("com.marer.reflect.Person");
Person p = (Person) clazz.newInstance();
暴力反射獲取類的隱藏建構函式:Constructor.setAccessible(true);

3、利用Method 獲取類方法
Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的
methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法
Method m = clazz.getMethod("t2",String.class);//獲取指定方法t2

4、反射呼叫t2方法
Object o = clazz.newInstance();
m.invoke(o,"123");

package clazz;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class TestClazz {

    public static void main(String[] args) throws Exception{
        try {
            Class<?> clazz = Class.forName("clazz.Test01");
            //獲取本類的所有方法,存放入陣列
            Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的
            methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法
            Method m = clazz.getMethod("t2",String.class);
            Object o = clazz.newInstance();
            m.invoke(o,"123");
            System.out.println("-------------------------");
            for (Method method : methods) {
                System.out.println("方法名:"+method.getName());
                //獲取本方法所有引數型別,存入陣列
                Class<?>[] getTypeParameters = method.getParameterTypes();
                if(getTypeParameters.length==0){
                    System.out.println("此方法無引數");
                }
                for (Class<?> class1 : getTypeParameters) {
                    String parameterName = class1.getName();
                    System.out.println("引數型別:"+parameterName);
                }
                System.out.println("****************************");
            }

            Constructor<?>[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println("構造器名:"+constructor.getName());
            }

            Constructor<?> c1 = clazz.getConstructor(null);
            System.out.println("構造器名:"+c1.getName());
            Test01 o1 = (Test01)c1.newInstance();
            System.out.println(o1);
            Constructor<?> c2 = clazz.getConstructor(String.class, String.class);
            System.out.println("構造器名:"+c2.getName());
            Test01 o2 = (Test01)c2.newInstance("1", "1");
            System.out.println(o2);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

 



 
主要功能
Class.forName(xxx.xx.xx)返回的是一個類。
Class.forName(xxx.xx.xx)的作用是要求JVM查詢並載入指定的類,也就是說JVM會執行該類的靜態程式碼段。 
A a = (A)Class.forName(“pacage.A”).newInstance();//這和你 A a = new A(); 是一樣的效果。

首先,通過Class獲取類的位元組碼
Class clazz = Class.forName("clazz.Test01");
1、獲取類的屬性
  //獲取類的屬性物件,需要填寫屬性物件的名稱
  Field f1=c.getField("name");//只能獲取public的物件
  Field f2=c.getDeclaredField("age");//可以獲取到private的物件,這很吊吧
  f2.setAccessible(true);//如果屬性是私有的,那麼就需要設定可訪問
2、利用Constructor建立物件
Constructor c = clazz.getConstructor(null);//獲取無參的建構函式
Constructor c = clazz.getConstructor(String.class);//獲取引數為String的建構函式
Constructor c = clazz.getConstructor(String.class, int.class);//獲取引數為String,int的建構函式
Constructor c = clazz.getDeclaredConstructor(List.class);//獲取隱藏為private的建構函式
c.setAccessible(true);//暴力反射
建立物件的另外一種途徑,反射出類的無參建構函式並建立物件
Class clazz = Class.forName("com.marer.reflect.Person");
Person p = (Person) clazz.newInstance();
暴力反射獲取類的隱藏建構函式:Constructor.setAccessible(true);
3、利用Method 獲取類方法
Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的
methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法
Method m = clazz.getMethod("t2",String.class);//獲取指定方法t2

4、反射呼叫t2方法
Object o = clazz.newInstance();
m.invoke(o,"123");

package clazz;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class TestClazz {

    public static void main(String[] args) throws Exception{
        try {
            Class<?> clazz = Class.forName("clazz.Test01");
            //獲取本類的所有方法,存放入陣列
            Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的
            methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法
            Method m = clazz.getMethod("t2",String.class);
            Object o = clazz.newInstance();
            m.invoke(o,"123");
            System.out.println("-------------------------");
            for (Method method : methods) {
                System.out.println("方法名:"+method.getName());
                //獲取本方法所有引數型別,存入陣列
                Class<?>[] getTypeParameters = method.getParameterTypes();
                if(getTypeParameters.length==0){
                    System.out.println("此方法無引數");
                }
                for (Class<?> class1 : getTypeParameters) {
                    String parameterName = class1.getName();
                    System.out.println("引數型別:"+parameterName);
                }
                System.out.println("****************************");
            }

            Constructor<?>[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println("構造器名:"+constructor.getName());
            }

            Constructor<?> c1 = clazz.getConstructor(null);
            System.out.println("構造器名:"+c1.getName());
            Test01 o1 = (Test01)c1.newInstance();
            System.out.println(o1);
            Constructor<?> c2 = clazz.getConstructor(String.class, String.class);
            System.out.println("構造器名:"+c2.getName());
            Test01 o2 = (Test01)c2.newInstance("1", "1");
            System.out.println(o2);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}