一.什麼是反射
反射機制是在運作狀态中,對于任何一個類,都知道它的屬性和方法,對于任何一個對象,都知道它的方法和屬性
二.反射的好處
1.在運作中判斷任意一個對對象所屬的類
2.在運作中構造任意一個類的對象
3.在運作中判斷任意一個類所具有的成員變量和方法
4.在運作中調用任意一個對象的方法
5.動态代理
三.怎麼使用
反射包都在reflect包中
有三種方式擷取反射對象
一.擷取反射對象
1.Class.forName(全類名)–一般用這個
2.類名.Class
3.對象.getClass()方法
public static void main(String[] args) throws ClassNotFoundException {
//Class.forName(全類名)
Class perClazz=Class.forName("com.crc.test.person");
System.out.println(perClazz);
//類名.Class
Class perClazz1=person.class;
System.out.println(perClazz1);
//對象.getClass()方法
person per=new person();
Class perClazz3=per.getClass();
System.out.println(perClazz3);
}
列印結果
class com.crc.test.person
class com.crc.test.person
class com.crc.test.person
二.擷取方法
perClazz.getDeclaredMethods();擷取本類所有方法(包括私有)
perClazz.getMethods();擷取所有公共方法(1本類,父類,接口。2非私有)
public static void main(String[] args) throws ClassNotFoundException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
System.out.println(perClazz);
//擷取方法
Method[] method=perClazz.getDeclaredMethods();
for (Method method2 : method) {
System.out.println(method2);
}
}
三.擷取接口
perClazz.getInterfaces();
public static void main(String[] args) throws ClassNotFoundException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取接口
Class[] method=perClazz.getInterfaces();
for (Class method2 : method) {
System.out.println(method2);
}
}
四.擷取父類
perClazz.getSuperclass();
public static void main(String[] args) throws ClassNotFoundException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取父類
Class method=perClazz.getSuperclass();
System.out.println(method);
}
五.擷取構造方法
perClazz.getConstructors();擷取多個
perClazz.getConstructor();擷取單個(有參根據傳入的是什麼類型找對應的構造函數)
public static void main(String[] args) throws ClassNotFoundException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取構造方法
Constructor[] method=perClazz.getConstructors();
for (Constructor method2 : method) {
System.out.println(method2);
}
}
Constructor constructor=perClazz.getConstructor(int.class);有參根據傳入的是什麼類型找對應的構造函數
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
Constructor constructor=perClazz.getConstructor(int.class);
//修改private的通路權限
person per =(person) constructor.newInstance();
System.out.println(constructor);
}
列印結果
public com.crc.test.person(int)
六.擷取所有的屬性
perClazz.getDeclaredFields();擷取本類所有屬性(包括私有)
perClazz.getFields();擷取所有公共屬性(1本類,父類,接口。2非私有)
public static void main(String[] args) throws ClassNotFoundException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取所有公有屬性
Field[] file=perClazz.getFields();
for (Field file2 : file) {
System.out.println(file2);
}
}
七.擷取目前反射所代表類對象
perClazz.newInstance();
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取所代表對象
Object Obj=perClazz.newInstance();
person per=(person) Obj;
per.intefaceMethod();
}
八.操作屬性
下面這段代碼操作age
file.set(per,2);
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取所代表對象
Object Obj=perClazz.newInstance();
person per=(person) Obj;
Field file=perClazz.getDeclaredField("age");
//修改private的通路權限
file.setAccessible(true);
file.set(per,);//類似于setAge(),差別是通路private要加上setAccessible
System.out.println(per.getAge());
}
九.操作方法
method.invoke(per,null);,和操作屬性類似
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
//Class入口
Class perClazz=Class.forName("com.crc.test.person");
//擷取所代表對象
Object Obj=perClazz.newInstance();
person per=(person) Obj;
Method method=perClazz.getDeclaredMethod("intefaceMethod2");
//修改private的通路權限
method.setAccessible(true);
method.invoke(per,null);
}