Java反射 | 青训营笔记

115 阅读4分钟

这是我参与【第四届青训营】笔记创作活动的第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(反射机制)详解 - 简书

网址:www.jianshu.com/p/2315dda64…