目录
1.什么是反射?
java反射(Reflection)是可以让我们在运行时获取类的方法,属性,父类,接口等类的内部信息的机制。反射本质上是一个“反着来”的过程。通过new 创建一个类的实例时,实际是由Java虚拟机根据这个类的Class对象在运行时构建出来的,而反射是通过一个类的Class对象来获取它的定义信息,从而我们可以访问到它的属性、方法,知道这个类的父类、实现了哪些接口等信息。
简单来说,
反射是一种机制,利用反射机制动态的实例化对象、读写属性、调用方法、构造函数。
2.反射用处?
- 获取任意类的名称,package信息,所有属性,方法,注解,类型,类加载器等
- 获取任意对象的属性,并且能改变对象的属性
- 调用任意对象的方法
- 判断任意一个对象的所属类
- 实例化任意一个类的对象
- 通过反射我们可以实现动态装配,降低代码的耦合度,动态代理等
3.如何使用反射
一切与反射相关的代码都从获取类对象开始
3.1.类名:class
Class<Student> stuClass = Student.class;
System.out.println("获取类的全路径名"+stuClass.getName());
System.out.println("获取简单类名"+stuClass.getSimpleName());
System.out.println("获取包名"+stuClass.getPackage());
3.2.对象名:getClass
Student stu=new Student();
Class<? extends Student> stuClass = stu.getClass();
System.out.println("获取类的全路径名"+stuClass.getName());
System.out.println("获取简单类名"+stuClass.getSimpleName());
System.out.println("获取包名"+stuClass.getPackage());
3.3.Class.forName("类的全路径")
Class<?> stuClass = Class.forName("com.zking.entity.Student");
System.out.println("获取类的全路径名"+stuClass.getName());
System.out.println("获取简单类名"+stuClass.getSimpleName());
System.out.println("获取包名"+stuClass.getPackage());
4.传统实例化与反射实例化的区别
4.1.传统实例化
Student stu=new Student();
4.2.反射实例化
Class<?> stuClass = Class.forName("com.zking.entity.Student");
//通过反射机制动态的实例化对象
Object stu = stuClass.newInstance();
注:1.Class.forName指定全路径名必须正确哦。否则就会报ClassNotFoundException(类没有发现异常)错误
2.在运行期间,一个类,类对象只能创建一个
5.反射应用
5.1.获取Field类相关
方法名 | 用途 |
getField(String name) | 获取共有的单个属性 |
getFields() | 获取所有共有的属性 |
getDeclaredField(String name) | 获取共有的,私有的,受保护的,最终的,静态的等等的单个属性(public和非public) |
getDeclaredFields() | 获取共有的,私有的,受保护的,最终的,静态的等等的多个属性(public和非public) |
setAccessible(boolean flag) | 设置权限,默认值false,设置true使私有成员允许访问 |
set(Object,Object) | 属性赋值 |
get(Object) | 获取属性 |
//1.获取共有的单个属性
//Field field = stuClass.getField("age");
//2.获取共有的,私有的,受保护的,最终的,静态的等等的单个属性
// Field field= stuClass.getDeclaredField("sname");
//3。获取所有共有的属性
// Field[] fields = stuClass.getFields();
//4.获取所有类型的属性
// Field[] fields = stuClass.getDeclaredFields();
// for (Field field : fields) {
// System.out.println("属性名"+field.getName());
// System.out.println("属性类型"+field.getType());
// System.out.println("访问修饰符"+field.getModifiers());
// System.out.println("---------");
// }
//5.属性赋值
Field field = stuClass.getField("age");
Field field = stuClass.getDeclaredField("sname");
//设置权限
field.setAccessible(true);
//参数:1.对象名,2.属性值
field.set(stu,"huahua");
//6.获取属性
Object sname = field.get(stu);
System.out.println(sname);
注:在对类中私有属性赋值时必须设置访问限权
5.2.获取Method类相关
方法名 | 用途 |
getMethod(String name, Class<>… parameterTypes) | 获取共有的单个方法 |
getMethods() | 获取所有共有的方法 |
getDeclaredMethods(String name,Class<>… parameterTypes) | 获取所有共有的,私有的,受保护的,最终的,静态的 |
getDeclaredMethod() | 获取单个共有的,私有的,受保护的,最终的,静态的等等的方法 |
invoke(Object obj, Object… args) | 执行方法 |
//调用方法:method
//方法分类:
// 无返回无参数
//无返回有参数
//有返回无参数
//有返回有参数
//1.获取共有的单个方法
Method method = stuClass.getMethod("hello");
//2.获取单个共有的,私有的,受保护的,最终的,静态的等等的方法
Method method = stuClass.getDeclaredMethod("hello",String.class);
Method method = stuClass.getDeclaredMethod("add", Integer.class, Integer.class);
//3.获取所有共有的方法
Method[] methods = stuClass.getMethods();
//4 获取所有公共的,私有的,受保护的,最终的,静态的等等的方法
Method[] methods = stuClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println("方法名"+method.getName());
System.out.println("访问修饰符:"+method.getModifiers());
System.out.println("返回类型:"+method.getReturnType());
System.out.println("方法参数数量"+method.getParameterCount());
System.out.println("=========");
}
//5.调用方法
Method method = stuClass.getMethod("hello",String.class);
Method method = stuClass.getDeclaredMethod("add", Integer.class, Integer.class);
//设置权限
method.setAccessible(true);
//参数1:实例化对象名
//参数2:方法本身所需参数
Object returnValue = method.invoke(stu,3,4);
System.out.println(returnValue);
5.3.获取constructor类相关
方法名 | 用途 |
getConstructor(Class<>… parameterTypes) | 获取单个公共的构造函数 |
getConstructors() | 获取所有公共的构造函数 |
getDeclaredConstructor(Class<>… parameterTypes)· | 获取单个公共或非公共的构造函数 |
getDeclaredConstructors() | 获取所有的构造函数(public 和非 public ) |
//获取单个公共的构造函数
Constructor<?> constructor = stuClass.getConstructor(String.class,String.class);
//获取所有公共的构造方法
Constructor<?>[] constructor = stuClass.getConstructors();
for (Constructor<?> constructor1 : constructor) {
System.out.println(constructor1);
}
//获取单个公共或非公共的构造函数
Constructor<?> constructor = stuClass.getDeclaredConstructor(String.class);
System.out.println(constructor);
//获取类中所有构造方法(public和非public)
Constructor<?>[] constructors = stuClass.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
构造函数属性赋值
//获取单个公共的构造函数
// Constructor<?> constructor = stuClass.getConstructor(Integer.class);
//获取单个公共或非公共的构造函数
// Constructor<?> constructor = stuClass.getDeclaredConstructor(Integer.class);
//设置权限
// constructor.setAccessible(true);
// 参数:方法本身所需参数
// Object hh = constructor.newInstance(7);
// System.out.println(hh);