1. 程式人生 > >Java的反射基礎技術

Java的反射基礎技術

 今天本人給大家講解一下Java的反射基礎技術,如有不對的或者講的不好的可以多多提出,我會進行相應的更改,先提前感謝提出意見的各位了!!!

  什麼是反射?

   反射它是根據位元組碼檔案可以反射出類的資訊、欄位、方法、構造方法等內容,還可以建立物件呼叫方法,我們稱它為反射技術。

  如何通過反射獲取Class物件了?

   它有三種方法,1.通過Class獲取類物件

                            2.通過getClass()方法獲取類物件

                        3.通過Class.forName(“完整類名”)獲取類物件

 

   案例:通過反射獲得Class物件的3種方法

Class c1 = ReflectionBasic.class;
Class c2 = new ReflectionBasic().getClass();
Class c3 = Class.forName("reflection.getClassObject.ReflectionBasic");

System.out.println(c1);
System.out.println(c2);
System.out.println(c3);

 執行結果:

 

 

 注意:Class.forName()它除了能獲取Class物件,還可以將獲取的類物件自動載入到JVM虛擬機器的記憶體中去 ,下面案例的執行結果可以看出程式碼輸出的static靜態程式碼塊一個泛型的C4和C5物件,可是隻有C5輸出了static,這就說明了使用Class.forName()可以將類物件載入到JVM虛擬機器的記憶體中去。

  案例:

 //通過輸出OtherTest反射物件
 Class<?> c4 = OtherTest.class;
System.out.println("此輸出物件是C4==============================="+c4);
Class<?> c5 = Class.forName("reflection.getClassObject.OtherTest");
System.out.println("此輸出物件是C5==============================="+c4);
class OtherTest{
static {
System.out.println("你好呀!!!寶寶們!!!");
}
}

   執行結果:

 

 

  獲取反射類的資訊

  在java.lang.reflect包下有很多反射類資訊的類

  反射類的資訊

  介面類:

public interface IReflection {
}

  父類:

public class Reflection {
}

  主類:

public class ReflectionInfo extends Reflection implements IReflection {
    public static void main(String[] args) {
        //建立類的物件
        Class<?> c1 = ReflectionInfo.class;
        //獲取反射ReflectionInfo類的================================修飾符
        int modifiers = c1.getModifiers();//得到的是一個整數那麼我們就需要轉換了
        System.out.println(modifiers);
        String sModifiers = Modifier.toString(modifiers);//轉換後得到的資訊
        System.out.println(sModifiers);
        System.out.println("以上是獲取反射ReflectionInfo類的================================修飾符");
        //獲取反射ReflectionInfo類的================================完整類名
        String name = c1.getName();
        System.out.println(name);
        //獲取反射ReflectionInfo類的================================簡易類名
        String simpleName = c1.getSimpleName();
        System.out.println(simpleName);
        System.out.println("以上是獲取反射ReflectionInfo類的================================完整類名和簡易類名");
        //獲取反射ReflectionInfo類的================================完整父類名
        Class<?> superclass = c1.getSuperclass();
        System.out.println(superclass.getSuperclass());
        //獲取反射ReflectionInfo類的================================簡易父類名
        System.out.println(superclass.getSimpleName());
        System.out.println("以上是獲取反射ReflectionInfo類的================================完整父類名和簡易父類名");
        //獲取反射ReflectionInfo類的================================介面,由於介面可以是多個我們需要通過遍歷來輸出出來
        Class<?>[] interfaces = c1.getInterfaces();
        if(interfaces.length>0){
            for (int i = 0; i < interfaces.length;i++){
                //獲取反射ReflectionInfo類的================================完整介面名
                System.out.println(interfaces[i]);
                //獲取反射ReflectionInfo類的================================簡易介面名
                System.out.println(interfaces[i].getSimpleName());
            }
        }
    }
}

執行結果:

 

 

通過反射技術訪問欄位(分private和public修飾)

錯誤案例:通過getFile()方法得到private屬性的值,會報錯

public class AccessFiled {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        //建立Class物件
        Class<?> c1 = Company.class;
        //返回返回的公共欄位public
        Field field = c1.getField("name");
        //通過反射技術建立物件例項,預設呼叫無參構造哦
        Object obj = c1.newInstance();//此方法相當於new一個Company物件
        field.set(obj,"無名公司");  //設定name的欄位值
        System.out.println(obj);
        System.out.println(field.get(obj));//輸出name的欄位值

        //返回返回的公共欄位public
        Field fields = c1.getField("id");
        //通過反射技術建立物件例項,預設呼叫無參構造哦
        field.set(obj,"00001");  //設定name的欄位值
        System.out.println(field.get(obj));//輸出name的欄位值

    }
}
class Company{
    public String name;
    private int id;
}

執行結果:

 

正確案例:使用getDeclaredField()方法得到private修飾的id值,這個是可以得到任意修飾符修飾的欄位

   

public class AccessFiled {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        //建立Class物件
        Class<?> c1 = Company.class;
        //返回返回的公共欄位public
        Field field = c1.getField("name");
        //通過反射技術建立物件例項,預設呼叫無參構造哦
        Object obj = c1.newInstance();//此方法相當於new一個Company物件
        field.set(obj,"無名公司");  //設定name的欄位值
        System.out.println(obj);
        System.out.println(field.get(obj));//輸出name的欄位值

        //返回返回的公共欄位public
        Field fields = c1.getDeclaredField("id");
        //通過反射技術建立物件例項,預設呼叫無參構造哦
        field.set(obj,"00001");  //設定name的欄位值
        System.out.println(field.get(obj));//輸出name的欄位值

    }
}
class Company{
    public String name;
    private int id;
}

執行結果:

 

通過反射技術呼叫方法

public class CallObject {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //建立Class物件
        Class<?> c1 = Company.class;
        //反射shou()方法
        Method method = c1.getMethod("show", null);//前面的引數是方法名。後面的是方法的返回值型別
        //通過反射建立例項
        Object obj = c1.newInstance();
        System.out.println("無參==========="+method.invoke(obj,null ));
        System.out.println(obj);
        Method shous = c1.getMethod("shows",String.class);
        shous.invoke(obj,"無名公司");
        //反射shows()方法帶(引數列表型別)
        System.out.println("有參==========="+obj);;
    }
}
class Company{
    public String name;
    private int id;

    public void show(){
        System.out.println("show=====方法");
    }
    public void shows(String name){
        System.out.println("shows======方法");
        this.name = name;
    }



    @Override
    public String toString() {
        return "Company{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}

執行結果:

 

 

  Java的反射基礎講解完畢,又不懂或者不理解的可以在評論區給本人留言,我會及時回覆大家