Java中的反射

目录

反射的概念和作用

获得Class的三种方法

获得Constructor类实例

构造方法访问权限为public

构造方法访问权限为private

有参的构造方法

获得Field实例

获得Method实例

反射优缺点


在没有反射时如何使用一个类?

  1. 已知一个类的类名,以及、类中的方法属性、构造方法
  2. 使用new关键字创建对象
  3. 使用对象调用方法和属性

那么仅仅知道一个类名该如何得到类的信息呢?

反射的概念和作用

        JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个 类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 java语言的反射机制。

作用:动态获取类的信息

获得Class的三种方法

        User user = new User();

        Class aClass = user.getClass();

        Class aClass1 = Class.forName("User");

        Class aClass2 = User.class;
        System.out.println(aClass==aClass1);//true
        System.out.println(aClass == aClass2);//true

也就是说只要是同一个类,获得的class对象就是同一个。

获得Constructor类实例

Constructor实例通过Class实例获得,Class类中定义了如下方法

● Constructor getConstructor(Class... parameterTypes) : 通过指定参数类型,返回构造方法实例

除了获得构造方法的基本信息,还可以创建实例

● newInstance(Object... initargs) :创建实例

构造方法访问权限为public

Constructor constructor = c.getConstructor();//获取类中的无参构造方法
Object o = constructor.newInstance();

构造方法访问权限为private

Constructor constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
Object o = constructor.newInstance();

有参的构造方法

Constructor constructor = c.getConstructor(String.class,int.class);
Object tom = constructor.newInstance("tom",1);

获得Field实例

获得Field实例,都是通过Class中的方法实现

● public Field getField(String name)通过指定Field名字,返回 Field实例.

● 注意Field的访问权限

作用:Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也 可以对属性进行赋值

public static void main(String[] args) throws Exception {    
    Class c = Class.forName("User");    
    Constructor constructor = c.getConstructor();//获取类中的无参构造方法    
    Object object = constructor.newInstance();    
    HashMap map = new HashMap<>();    
    map.put("name","jim");    
    map.put("id",1);    
    Field[] fields = c.getFields();//取出所有属性    
    for (Field f :fields) {        
        f.set(object,map.get(f.getName()));    
    }    
    System.out.println(object);
}

获得Method实例

Method类将类中的方法进行封装,可以动态获得方法的信息,例如

● getName:获得方法名字

● getParameterTypes:获得方法参数类型

除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法

● invoke(Object obj, Object... args) :使用obj调用该方法,参数为args

String cname = "User";//类的地址
        Class c = Class.forName(cname);//通过类的地址加载类,获得到类的Class对象

        Constructor constructor =  c.getDeclaredConstructor();
        constructor.setAccessible(true);
        Object object = constructor.newInstance();

        /*
           c.getMethods()获得类中所有的公共的成员方法
           getMethod("getId",type) 获得公共的指定名称参数的成员方法
            c.getDeclaredFields();得类中所有的成员方法(包含私有的)
            c.getDeclaredMethod(name,type)
         */
          Method method =  c.getMethod("setId",int.class);
                method.invoke(object,100);

System.out.println(object);

反射优缺点

优点:

1.增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作 

2.提高代码的复用率,比如动态代理 

3.可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态调用

缺点:

 1.反射会涉及到动态类型的解析,导致性能要比非反射调用更低 

2.使用反射技术通常要在一个没有安全限制的程序运行. 

3.反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象性 

你可能感兴趣的:(java,开发语言)