这是我参与【第四届青训营】笔记创作活动的第4天
Java反射
Java反射机制可以让我们在运行期中获取任何一个类的接口、变量以及方法等信息。还提供我们在运行期实例化对象,通过get()/set()方法获取、修改变量值。
获取Class对象
Java中所有的类型都有关联的Class类对象,通过类名获取Class对象:
//’className‘为类名,运行时的类名字符串
Class clazz = Class.forName(className);
获取类名
在不知道类名的情况下也可以通过反射机制获取类名。第一种方法,获取类的全限定类名,即包括包名:
//'clazz'为Class对象
String className = clazz.getName();
第二种方法,只获取类的类名,不带包名:
//'clazz'为Class对象
String className = clazz.getSimpleName();
获取修饰符
通过Class对象访问一个类的修饰符,比如public、private、static等:
//'clazz'为Class对象
int modifiers = clazz.getModifiers();
返回值为int型数据,由于每个修饰符都是一个标识位,所以可以通过java.lang.reflect.Modifier类中的方法检测修饰符的类型,具体方法如下:
//'modifiers'为Class对象获取修饰符方法的返回值
Modifier.isAbstract(int modifiers);
Modifier.isFinal(int modifiers);
Modifier.isInterface(int modifiers);
Modifier.isNative(int modifiers);
Modifier.isPrivate(int modifiers);
Modifier.isProtected(int modifiers);
Modifier.isPublic(int modifiers);
Modifier.isStatic(int modifiers);
Modifier.isStrict(int modifiers);
Modifier.isSynchronized(int modifiers);
Modifier.isTransient(int modifiers);
Modifier.isVolatile(int modifiers);
获取包信息
通过反射机制获取Class对象包信息:
//'clazz'为Class对象
Package package = clazz.getPackage();
获取父类
通过反射获取父类:
//'clazz'为Class对象
Class superClass = clazz.getSuperClass();
由于返回值类型为Class,所以可以再对’superClass‘进行父类获取操作。
获取实现的接口
通过反射获取类的实现接口:
//'clazz'为Class对象
Class[] interfaces = clazz.getInterfaces();
由于一个类可以实现多个接口,因此 getInterfaces(); 方法返回一个 Class 数组,在 Java 中接口同样有对应的 Class 对象。
获取构造器
通过反射获取构造器类的实例:
//'clazz'为Class对象
Construct[] constructors = clazz.getConstructors();
被public修饰的构造方法被返回至Construct数组中。
通过方法类型获取指定的构造方法:
//'clazz'为Class对象
Construct constructor = clazz.getConstructor(new Class[]{String.class});
获取构造方法参数类型为String的公有构造方法,由于构造方法的参数决定了构造方法的唯一,所以此方法最多只能获取到一个构造方法返回,如果此构造方法不存在,就会抛出NoSuchMethodException异常。
获取构造方法的参数信息:
//'constructor'为构造器对象
Class[] parameterTypes = constructor.getParameterTypes();
通过获取到的构造器方法实例化一个类:
//'clazz'为Class对象
Construct constructor = MyClass.class.getConstructor(String.class);
MyClass myClass = (MyClass) constructor.newInstance("param1");
constructor.newInstance()方法的方法参数是一个可变参数列表,但是当你调用构造方法的时候你必须提供精确的参数,即形参与实参必须一一对应。
获取方法
通过反射获取Class对象中的方法:
//'clazz'为Class对象
Method[] methods = clazz.getMethods();
将类中的公有方法返回至Method[]数组中。
通过方法的参数类型获取指定的方法:
//'clazz'为Class对象
Method method = clazz.getMethod("methodName",new Class[]{String.class});
第一个字符串参数为返回方法名称,第二个参数为方法参数类型。如果方法没有参数则可以通过如下代码实现:
//'clazz'为Class对象
Method method = clazz.getMethod("methodName",null);
获取方法参数:
//'clazz'为Class对象
Method method = clazz.getMethod("methodName",new Class[]{String.class});
Class[] parameterTypes = method.getParameterTypes();
获取方法的返回类型:
//'clazz'为Class对象
Method method = clazz.getMethod("methodName",new Class[]{String.class});
Class returnType = method.getReturnType();
调用方法:
//'clazz'为Class对象
Method method = MyClass.class.getMethod("methodName",String.class);
Object returnValue = method.invoke(null,"param1")
传入的 null 参数是你要调用方法的对象,如果是一个静态方法调用的话则可以用 null 代替指定对象作为 invoke()的参数,在上面这个例子中,如果 methodName 不是静态方法的话,你就要传入有效的 MyClass 实例而不是 null。 Method.invoke(Object target, Object … parameters)方法的第二个参数是一个可变参数列表,但是你必须要传入与你要调用方法的形参一一对应的实参。
获取变量
访问公有的变量。
//'clazz'为Class对象
Field[] fields = clazz.getFields();
或者
//'clazz'为Class对象
Field field = clazz.getField(String name);
访问私有变量:
//'clazz'为Class对象
Field[] fields = clazz.getDeclaredFields();
或者
//'clazz'为Class对象
Field field = clazz.getgetDeclaredField(String name);
标题:Java Reflection(反射机制)详解 - 简书