Java的反射基礎技術
阿新 • • 發佈:2020-03-20
今天本人給大家講解一下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的反射基礎講解完畢,又不懂或者不理解的可以在評論區給本人留言,我會及時回覆大家