参考文献:
https://www.cnblogs.com/ysocean/p/6516248.html
https://www.cnblogs.com/whgk/p/6122036.html
反射是什么
Java 反射就是在程序运行时,都能够知道这个类的属性和方法;对于任意一个对象,都能调用他的任意方法和属性,并且能够改变他的属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射能够做什么
利用反射可以在运行状态下获得已知类名的 class 的内部信息,包括修饰符,属性,方法等,还可以对属性进行改变或调用方法。利用反射可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码连接,降低耦合度;还有动态代理的实现等。
概括起来为:
在运行时判断任何一个对象所属的类。
在运行时获得任意类的成员变量和方法。
在运行时修改任意对象的属性或者调用方法。
在运行时构造任意一个类的对象。
生成动态代理。(待补充)
注意:
反射使用不当会造成很高的资源消耗。
反射的具体实现
1、在运行时判断任意一个对象所属的类
package test;
//通常在传入的对象是 Object 类,但是需要知道确切类型时使用这个方法。
Person p = new Person();
Class c = p.getClass();
获得 Class 还有其余两种方法:
//Class.forName() 方法用的最多,但是可能抛出 ClassNotFoundException 异常
Class c1 = Person.class;
Class c2 = Class.forName("test.Person");
注意:
一个类在 JVM 中只有一个 class 实例,c、c1、c2 用 equals 比较都相等。
2、通过 Class API 获得有关类的具体信息(成员变量、成员方法、接口等)。
getName(): 获得类的完整名字。
getFields(): 获得类的 public 类型的属性。
getDeclaredFields(): 获得类的所有属性,包括 private 声明的和继承类。
getMethods(): 获得类的 public 类型的方法。
getDeclaredMethods(): 获得类的所有方法,包括 private 声明的和继承类。
getMethod(String name, Class[] parameterTypes): 获得雷德特定方法,name 参数指定方法的名字, parameterTypes 参数指定方法的参数类型。
getConstructors(): 获得类的 public 类型的构造方法。
getConstructor(Class[] parameterTypes): 获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance(): 通过类的不带参数的构造方法创建这个类的一个对象。
实例:
//获得类的名字
String name = c1.getName();
//获得 public 的属性
Field[] fields = c1.getFields();
//获得所有属性
Field[] allFields = c1.getDeclaredFields();
//如果属性中有私有的,要打开可见权限
allFields.setAccessable(true);
//获得 public 的方法
Method[] methods = c1.getMethods();
//获得所有属性的方法
Method[] allMethods = c1.getDeclareMethods();
//获得指定属性
Field field = c1.getField("age");
Field field1 = c1.getDeclareField("age");
field1.setAccessable(true);
//创建这个类的一个对象
Object newC = c1.newInstance();
//将 newC 的 field1 重置
field1.set(newC, "1111");
//通过 get 可以得到最新的值-->"1111"
field1.get(newC);
//获取构造方法
Constructor[] con = c1.getConstructors();
3、通过当前类获得父类的信息
父类:
public class Parent{
public String publicField = "publicField";
protected String protectedField = "protectedField";
String defaultField = "defaultField";
private String privateField = "privateField";
}
子类:
public class Son extends Parent{
}
测试类:
public class Test{
public void test throws Exception(){
//第一步:获得子类对像
Class newcc =Class.forName("test.Son");
Field ff = null;
//第二步:通过子类对象的 getSuperclass() 方法获得父类对象
for(; newcc != Object.class; newcc = newcc.getSuperclass()){
try{
//第三步:由父类对象获得其自身的相关信息
field = newcc.getDeclaredFiled("privateField");
field.setAccessable(true);
}catch(Exception e){
//这里不要有任何操作
}
}
}
}
网友评论