反射使用
什么是反射
- 反射是 Java 语言的一种特性
- 反射机制允许程序在运行时再加载、探知、使用哪些在编译时完全未知的类
反射的作用
- 在运行时探知任意一个实例所属的类
- 在运行时构造任意一个类的实例
- 在运行时探知任意一个类所具有的方法和属性
- 在运行时调用任意一个实力的方法
反射常用的API
java.lang.Class<T>
:类的类java.lang.reflect.Constructor<T>
:构造方法的类java.lang.reflect.Field
:属性的类java.lang.reflect.Method
:方法的类
反射的应用
获取Class对象
通过类名获取
package com.yaconit.reflect.entity;
class User{ }
Class clz = User.class();
通过实例化对象获取
User user = new User();
Class clz = user.getClass();
使用Class.forName()获取
Class clz = Class.forName("com.yaconit.reflect.entity.User");
获取类的信息
获取类名
获取该类型的完全限定名
Class clz = User.class();
String className = clz.getName();
获取该类型的类名
Class clz = User.class();
String className = clz.getSimpleName();
获取包名
Class clz = User.class();
Package classPackage = clz.getPackage();
String packageName = classPackage.getName();
获取父级类的Class实例
Class clz = User.class();
Class superClass = clz.getSuperclass();
获取所有实现的接口的Class实例
Class clz = User.class();
Class[] interfacesClasses = clz.getInterfaces();
获取修饰符
Class clz = User.class();
int modifiers = classObj.getModifiers();
if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC) {
System.out.println("这是一个公共类");
}else if ((modifiers & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
System.out.println("这是一个抽象类");
}else if ((modifiers & Modifier.FINAL) == Modifier.FINAL) {
System.out.println("这个类是 final 的");
}else if ((modifiers & Modifier.INTERFACE) == Modifier.INTERFACE) {
System.out.println("这是一个接口");
}
获取所有的内部类的Class实例
Class clz = User.class();
Class[] declaredClasses = clz.getDeclaredClasses();
获取外部类的Class实例
Class clz = User.class();
Class declaringClass = clz.getDeclaringClass();
获取构造方法对象
获取指定参数列表的public构造方法
Class clz = Person.class;
Constructor constructor = clz.getConstructor(String.class, Integer.class);
获取所有的public构造方法
Class clz = Person.class;
Constructor[] constructors = clz.getConstructors();
获取指定参数列表的构造方法
Class clz = Person.class;
Constructor constructor = clz.getDeclaredConstructor(String.class, Integer.class);
获取所有的构造方法
Class clz = Person.class;
Constructor[] constructors = clz.getDeclaredConstructors();
获取构造方法信息
获取构造方法的访问修饰符
Class clz = Person.class;
Constructor constructor = clz.getConstructor(String.class, Integer.class);
int modifier = constructor.getModifiers();
获取构造方法的参数列表
Class clz = Person.class;
Constructor constructor = clz.getConstructor(String.class, Integer.class);
Class[] params = constructor.getParameterTypes();
取消访问检查
可以使 Java 调用非 public
修饰的构造方法
Class clz = Person.class;
Constructor constructor = clz.getDeclaredConstructor(String.class, Integer.class);
constructor.setAccessible(true);
实例化对象
通过Class对象实现
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
通过构造方法实现
Class clz = Person.class;
Constructor constructor = clz.getDeclaredConstructor(String.class, Integer.class);
constructor.setAccessible(true);
Person person = (Person)constructor.newInstance("张三", 20);
获取属性对象
获取指定名称的public属性
Class clz = Person.class;
Field filed = clz.getField("name");
获取所有的public属性
Class clz = Person.class;
Field[] fileds = clz.getFields();
获取指定名称的属性
Class clz = Person.class;
Field filed = clz.getDeclaredField("name");
获取所有的属性
Class clz = Person.class;
Field[] fileds = clz.getDeclaredFields();
获取属性信息
获取属性名
Class clz = Person.class;
Field filed = clz.getField("name");
String filedName = field.getName();
获取属性类型
Class clz = Person.class;
Field filed = clz.getField("name");
String typeName = field.getType().getName();
获取属性修饰符
Class clz = Person.class;
Field filed = clz.getField("name");
int modifier = field.getModifiers();
访问属性
获取属性值,返回指定的数据类型
获取非静态属性的值
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
Field filed = clz.getField("name");
String name = field.getString(person);
获取静态属性的值
Class clz = Person.class;
Field filed = clz.getField("name");
String name = field.getString(null);
获取属性的值,返回Object
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
Field filed = clz.getField("name");
Object name = field.get(person);
将指定类型的值设置给属性
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
Field filed = clz.getField("name");
field.setString(person,"张三");
设置属性的值
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
Field filed = clz.getDeclaredField("name");
field.set(person,"张三");
取消访问检查
可以使 Java 调用非 public
修饰的属性
Class clz = Person.class;
Field filed = clz.getField("name");
filed.setAccessible(true);
获取方法对象
获取指定名称的public方法
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
获取所有的public方法
Class clz = Person.class;
Method[] methods = clx.getMethods();
获取指定名称的方法
Class clz = Person.class;
Method method = clx.getDeclaredMethod("setName", String.class);
获取所有的方法
Class clz = Person.class;
Method[] methods = clx.getDeclaredMethods();
访问方法信息
获取方法名称
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
String methodName = method.getName();
获取方法返回值类型
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
String returnTypeName = method.getReturnType().getName();
获取方法的参数列表
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
Class[] params = method.getParameterTypes();
获取方法的访问修饰符
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
int modifier = method.getModifiers();
获取方法所属的类或接口的Class实例
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
Class declaringClass = method.getDeclaringClass();
获取方法抛出的异常类型
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
Class[] exceptions = method.getExceptionTypes();
方法调用
调用实例方法
无返回值
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
Method method = clx.getMethod("setName", String.class);
method.invoke(person, "张三");
有返回值
Class clz = Person.class;
Person person = (Person)classObj.newInstance();
Method method = clx.getMethod("getName");
Object name = method.invoke(person);
调用静态方法
Class clz = Person.class;
Method method = clx.getMethod("setName", String.class);
method.invoke(null, "张三");
取消访问检查
可以使 Java 调用非 public
修饰的方法
Class clz = Person.class;
Method method = clx.getDeclaredMethod("setName", String.class);
method.setAccessible(true);