14.反射
2022-04-29 本文已影响0人
星野君
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
一、反射案例
获取class方式:
public class Home {
public static void main(String[] args) {
// 第一种方式获取Class对象
Cat cat = new Cat(); // 这一new 产生一个Student对象,一个Class对象。
Class stuClass = cat.getClass(); // 获取Class对象
System.out.println(stuClass.getName());
// 第二种方式获取Class对象
Class stuClass2 = Cat.class;
// 第三种方式获取Class对象
try {
Class stuClass3 = Class.forName("com.ylf.test.Cat");
// 注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
通过反射调用方法:
public void Test()
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException {
Class cls = Class.forName("com.ylf.test.Cat");
Object o = cls.newInstance();
Method hi = cls.getMethod("xxx");
hi.invoke(o);
}
二、反射常用方法
- forName 返回指定类名name的Class对象
- newInstance 返回Class对象的实例
- getName 返回当初Class对象的名称
- getMethod 返回一个Method对象
- getDeclaredFields 返回Field对象的一个数组
- getClassloader 返回Class对象的加载器
三、类加载
反射加载是java实现动态语言的关键,也就是通过反射实现类动态加载
- 静态加载:编译时加载相关类,如果没有就则报错,依赖性太强
- 动态加载:运行时加载需要的类,如果运行时不用该类,即使不存在该类,也不会报错,降低了依赖性
类的加载时机:
- 当创建对象new时 //静态加载
- 当子类加载时父类也会被加载 //静态加载
- 调用类中的静态成员时 //静态加载
- 使用反射 //动态加载
类的加载过程图
image.png image.png
四、通过反射获取类的结构信息
- getName 获取类的全类名
- getSimpleName 获取简单类名
- getFields 获取所有public修饰的所有属性
- getDeclaredFields 获取所有属性
- getMethods 获取所有public的方法
- getDeclareFields 获取所有方法
- getConstructors 获取所有public构造器
- getDeclaredConstructors 获取所有构造器
- getPackage 返回包的信息
- getSuperClass 返回父类信息
- getInterfaces 返回接口信息
访问属性:
public void Test()
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class cls = Class.forName("com.ylf.test.Cat");
Object o = cls.newInstance();
//访问属性
final Field name = cls.getDeclaredField("name");
name.setAccessible(true); //爆破
System.out.println(name.get(o));
}
通过反射创建对象:
public void Test()
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class cls = Class.forName("com.ylf.test.Cat");
Object o = cls.newInstance();
final Constructor constructor = cls.getConstructor(String.class); // 参数是什么就对应哪个构造器
final Object c = constructor.newInstance("小黑"); // 这里参数实参
System.out.println(c);
}
得到private构造器:
public void Test()
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class cls = Class.forName("com.ylf.test.Cat");
Object o = cls.newInstance();
final Constructor constructor = cls.getDeclaredConstructor(String.class); // 参数是什么就对应哪个构造器
constructor.setAccessible(true);//爆破
final Object c = constructor.newInstance("小黑"); // 这里参数实参
System.out.println(c);
}