目录
反射的概念和作用
获得Class的三种方法
获得Constructor类实例
构造方法访问权限为public
构造方法访问权限为private
有参的构造方法
获得Field实例
获得Method实例
反射优缺点
在没有反射时如何使用一个类?
那么仅仅知道一个类名该如何得到类的信息呢?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个 类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 java语言的反射机制。
作用:动态获取类的信息
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实例通过Class实例获得,Class类中定义了如下方法
● Constructor getConstructor(Class... parameterTypes) : 通过指定参数类型,返回构造方法实例
除了获得构造方法的基本信息,还可以创建实例
● newInstance(Object... initargs) :创建实例
Constructor constructor = c.getConstructor();//获取类中的无参构造方法
Object o = constructor.newInstance();
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实例,都是通过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类将类中的方法进行封装,可以动态获得方法的信息,例如
● 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.反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象性