反射
1、概念
反射是java的动态机制,在运行状态中对于任意一个类,都能知道这个类所有的属性、方法、构造器。很多优秀的开源框架都是通过反射机制完成。
2、可以实现的功能
①在运行时判断任意一个对象所属的类。
②在运行时构造任意一个类的对象。
③在运行时判断任意一个类所具有的成员变量和方法。
④在运行时调用任意一个对象的方法。
⑤生成动态代理。
3、获取源头
//方式1、类名.class
Class<String> cls1 = String.class;
System.out.println(cls1);
//方式2、 对象.getClass()
Class cls2 = "".getClass();
System.out.println(cls2);
//方式3、 Class.forName(权限定路径) -->推荐
Class cls3 = Class.forName("java.lang.String");
4、反射操作构造器
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
/*
反射操作构造器
创建对象
反射操作方法
调用方法
反射操作属性
设置值获取值
*/
public class RelectDemo03 {
public static void main(String[] args) throws Exception {
test(User.class);
}
/*
反射操作构造器
创建对象
1) Class类中newInstance方法 内部创建对象时候默认调用空构造,否則抛出异常InstantiationException
2) 先获取构造器,在调用构造器的newIntance方法,并 创实参
Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[] getConstructors()
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor<?>[] getDeclaredConstructors()
*/
public static void testConstructor(Class<User> cls) throws Exception {
//1.Class类中newInstance方法
User obj = cls.newInstance();
System.out.println(obj);
//2.获取构造器
Constructor cons = cls.getConstructor();
Constructor cons2 = cls.getConstructor(int.class);
Constructor cons3 = cls.getDeclaredConstructor(String.class,String.class);
System.out.println(cons3);
//2.创建对象,指定调用 哪一个构造器
System.out.println(cons.newInstance());;
System.out.println(cons2.newInstance(1001));;
//如果是私有的内容,使用前忽略权限
cons3.setAccessible(true);
System.out.println(cons3.newInstance("zhangsan","234"));;
cons3.setAccessible(false);
}
//测试常用方法
public static void test(Class<User> cls){
System.out.println(String.class.getModifiers());;
System.out.println(Modifier.toString(String.class.getModifiers()));;
System.out.println(cls.getName());
System.out.println(cls.getSimpleName());
}
}
5、反射操作方法 调用方法
/*
反射操作方法
获取方法
cls.getMethod(方法名,参数类型的Class对象..)
cls.getMethods()
上面2个操作公共方法,包含父类中继承的
cls.getDeclaredMethod(方法名,参数类型的Class对象..)
cls.getDeclaredMethods()
上面2个操作所有方法,不包含继承的
注意: 如果私有方法注意权限问题
调用方法 Object invoke(Object obj, Object... args)
成员方法 ->对象
静态方法 ->对象|类
*/
public static void testMethod(Class<User> cls) throws Exception {
//所有方法
//Method[] methods = cls.getMethods();
Method[] methods = cls.getDeclaredMethods();
for(Method m : methods){
System.out.println(m);
}
//指定公共的方法
Method method = cls.getMethod("getName");
//创建对象
User user = cls.getConstructor(int.class,String.class,String.class).newInstance(1002,"yinwei","4321");
Method method2 = cls.getDeclaredMethod("setName", String.class);
method2.invoke(user,"suoyi");
//调用方法
System.out.println(method.invoke(user));;
//私有方法
//方法忽略权限问题
methods[4].setAccessible(true);
methods[4].invoke(user);
//静态方法
Method method3 = cls.getDeclaredMethod("haha");
System.out.println(method3);
//可以通过对象,可以设置为null
method3.setAccessible(true);
method3.invoke(user);
}
6、反射操作属性 设置值获取值
//测试操作属性
public static void testField(Class<User> cls) throws Exception {
//创建对象
User user = cls.getConstructor(int.class,String.class,String.class).newInstance(1002,"yinwei","4321");
//获取属性
Field field = cls.getDeclaredField("id");
//私有属性权限问题
field.setAccessible(true);
//设置值
field.set(user,2000);
//获取值
System.out.println(field.get(user));
System.out.println(Modifier.toString(field.getModifiers()));
}