一.反射机制
是在运行状态中,对任意一个类,都能知道这个类的所有属性和方法;
对于任意一个对象,都能调用它的任意属性和方法.
这种动态获取信息以及动态调用方法的功能称为java语言的反射机制.
二.Class类对象的实例化
java.lang.Class是一个类,这个类是反射操作的源头.有三种实例化方法.
方式一:调用Class提供的Class.getName(全类名) 常用
全类名:包名+类名
public class demo5 {
public static void main(String[] args) throws ClassNotFoundException {
Class aClass = Class.forName("day15.Student");
System.out.println(aClass);
}
}
方式二.使用类.class 一般用做参数传递
public class demo5 {
public static void main(String[] args) throws ClassNotFoundException {
Class cla=Student.class;
System.out.println(cla);
}
}
方式三:调用Object类的getClass()方法() 很少使用
public class demo5 {
public static void main(String[] args) throws ClassNotFoundException {
Student s = new Student();
Class aClass = s.getClass();
System.out.println(aClass);
}
}
三.反射实例化对象
一般对象的实例化操作需要new关键字和依靠构造方法完成,我们得到了Class类对象,可以通过反色来实现对象的实例化.
T newInstance(Object...initargs) 方法实现
class Test{
private int age;
public Test() {
System.out.println("无参");
}
}
class demo5 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class aClass = Class.forName("day15.Test");
Object o = aClass.newInstance();//相当于使用new调用了无参构造
}
}
反射完成的实例化操作是比new要复杂的,但是
什么时候用反射还是new呢?
在写代码的时候,明确知道现在要用什么类的,可以用new, 你不知道要用什么类,就可以用反射了。
反射调用构造方法,属性,成员方法
1.调用构造方法
最开始的时候我们使用,
Class<?> cls = Class.forName();
Object obj = cls.newInstance();
可以调用无参构造方法,怎么调有参呢.!
<1>Constructor<?>[] getConstructors() | 返回所有公共构造方法对象的数组 |
<2>Constructor<?>[] getDeclaredConstructors() | 返回所有构造方法对象的数组 |
<3>Constructor<T> getConstructor(Class<?>... parameterTypes) | 返回单个公共构造方法对象 |
<4>Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) | 返回单个构造方法对象 |
列如:获取单个构造方法,有参构造方法
class demo5 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class aClass = Class.forName("day15.Student");
Constructor constructor = aClass.getConstructor(int.class,String.class);
Object o = constructor.newInstance(12,"22");
System.out.println(o);
}
}
Constructor类用于创建对象的方法
方法名 | 说明 |
---|---|
T newInstance(Object...initargs) | 根据指定的构造方法创建对象 |
setAccessible(boolean flag) | 设置为true,表示取消访问检查 |
2.调用属性
Field[] getFields() | 返回所有公共成员变量对象的数组 |
Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |
Field getField(String name) | 返回单个公共成员变量对象 |
Field getDeclaredField(String name) | 返回单个成员变量对象 |
列如获取单个私有属性
class demo5 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class aClass = Class.forName("day15.Student");
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
Student o = (Student) aClass.newInstance();
name.set(o,"Lisa");
Object o1 = name.get(o);
System.out.println(o1);
}
}
3.调用成员方法
Method[] getMethods() | 返回所有公共成员方法对象的数组,包括继承的 |
Method[] getDeclaredMethods() | 返回所有成员方法对象的数组,不包括继承的 |
Method getMethod(String name, Class<?>... parameterTypes) | 返回单个公共成员方法对象 |
Method getDeclaredMethod(String name, Class<?>... parameterTypes) | 返回单个成员方法对象 |
例如调用单个私有的成员方法
class demo5 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class aClass = Class.forName("day15.Student");
Method show = aClass.getDeclaredMethod("show");
Student o = (Student) aClass.newInstance();
Object invoke = show.invoke(o);
System.out.println(invoke);
}
}