一、反射
1、什么是反射?
动态的获取类以及类中的成员,并可以调用该类成员。
2、应用场景:
提高了程序的可扩展性。
3、反射中最重要的一点:要先获取到那个类。
4、如何获取类呢?
无论new什么对象,都需要先获取字节码文件。Class类是Java对字节码文件的描述。
5、描述字节码文件的类:Class
name 类名 getName()
contructor 构造器 getContructor()
field 字段 getField()
method 方法 getMethod()
*每一个.class文件都可以生成一个Class对象。
6、如何获取一个字节码文件呢?
方式一: Object getClass() getClass()返回创造该对象的字节码对象
Class clazz = p.getClass();
!!该方法不适合反射技术,因为反射技术不明确具体类。
方式二:所有的数据类型都有自己对应的Class对象,表示方式很简单,每一个数据类型都有一个默认的静态的属性。.class,用该属性就可以获取到字节码文件对象。
Class clazz = Person.class
!!还是要用具体的类来调用class属性。
方式三:在Class类中有forName()方法,只需要通过类的完整名称就可以获取对应的字节码文件对象。
Class clazz = Class.forName("com.itcast.domain.Person");
二、如何根据给定名称获取到指定的Class对象后建立该类的对象呢?
根据给定的类名获取Class对象。
String className = " ";
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();//该方式默认用空参构造函数。
*一般被反射的类通常都有空参数的构造函数。
!!如果被反射的类只有带参构造函数,则会报java.lang.InstantiationException异常,说明没有调用到与之对应的构造函数。
如果给定类中没有空参数的构造函数该怎么办呢?
先通过Class获取指定的构造函数,再通过该构造函数进行实例化。
Constructor cons = clazz.getConstructor(String.class,int.class);
Object obj = cons.newInstance("lisi",23);
三、动态的获取字段
1、获取指定age字段
Field field = clazz.getField(" "); //无法获取私有字段
Field field = clazz.getDeclaredField(" "); //可以获取私有字段
2、获取非静态的字段操作必须有对象
Object obj = clazz.newInstance();
3、使用父类的方法将访问权限检查能力取消
field.setAccessible(true); //暴力访问
field.set(obj,40);
四、动态的获取方法
1、非静态,有参数的方法。
String className = " ";
Class clazz = Class.forName(className);
Method method = clazz.getMethod(" ",String.class,int.class);
Object obj = clazz.newInstance();
method.invoke(obj," ",40);
2、非静态,无参数的方法。
String className = " ";
Class clazz = Class.forName(className);
Method method = clazz.getMethod(" ",null);
Object obj = clazz.newInstance();
method.invoke(obj, null);
3、静态,无参数的方法。
String className = " ";
Class clazz = Class.forName(className);
Method method = clazz.getMethod(" ",null);
method.invoke(null, null);