反射

反射机制(java.Reflection)

反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并且能操作任意对象的的属性和方法。加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了完整的类的结构信息,就可以通过这个对象看到对应的类的结构。

反射

获取Class类的实例

  • 如果已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高

    Class c1 = Person.class;
    
  • 已知某个类的实例,调用该实例的getClass()方法获取Class对象

    Class c1 = person.getClass(); 
    
  • 已知一个类的全限定名,可通过Class类的静态方法forName()获取,会抛出ClassNotFoundException

    Class c1 = Class.forName("com.wx.dojo.Person");
    
  • 利用ClassLoader

获取类的运行时结构

  • 获取类的属性

    // 可以获取所有的属性
    Field[] declaredFields = aClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.println(declaredField);
    }
    // 只能找到public属性
    Field[] fields = aClass.getFields();
    for (Field field : fields) {
        System.out.println(field);
    }
    
  • 获取类的方法

    // 获取本类以及父类的所有public方法
    Method[] methods = aClass.getMethods();
    //获取本类的所有方法
    Method[] declaredMethods = aClass.getDeclaredMethods();
    

动态创建对象执行方法

创建一个Category的类,如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Category {
    private int id;
    private String name;

    private void sell(){
        System.out.println("sell" + this.name);
    }
}
  • 通过无参构造器创建一个对象

    /**
     * 通过无参构造器创建一个对象
     */
    Class aClass = category.getClass();
    Category instance = (Category) aClass.newInstance();
    System.out.println(instance);
    /**
     *结果:
     * Category(id=0, name=null)
     */
    
  • 没有无参构造器的时候通过有参构造器获取对象

    /**
     * 当类没有无参构造的时候通过获取有参构造器创建对象
     */
    Constructor constructor = aClass.getDeclaredConstructor(int.class, String.class);
    Category instance1 = (Category) constructor.newInstance(1,"香蕉");
    System.out.println(instance1);
    /**
     * 结果:
     * Category(id=1, name=香蕉)
     */
    
  • 调用对象的方法

    /**
     * 通过反射调用普通方法
     */
    Method setId = aClass.getDeclaredMethod("sell");
    // 设置私有的方法可以被访问
    setId.setAccessible(true);
    // 激活方法
    setId.invoke(instance1);
    /**
     * 结果:
     * sell香蕉
     */
    
  • 操作对象的属性

    /**
     * 通过反射操作属性
     */
    Field name = aClass.getDeclaredField("name");
    // 设置私有的属性可以被访问
    name.setAccessible(true);
    name.set(instance,"apple");
    System.out.println(instance.getName());
    
上一篇:flink sql 写 kudu


下一篇:如何在SAP Spartacus category 页面里拿到当前的category信息