反射机制学习

参考文献:
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){
              //这里不要有任何操作
           }
        }
    }
 }

你可能感兴趣的:(反射机制学习)