Java中的反射知识点(通俗讲解)
首先我得介绍以下常用的反射类, 然后给出相应的代码示例, 切记, 学会应用, 不要死记, 不要死记, 不要死记!
Class类
Class类是java.lang.Class包中的, 其常用到的方法如下(不需要死记, 用到的时候调用)
- 返回className的类或接口的Class对象
public static Class<?> forName(String className)
- 返回Class对象所对应类的父类的Class对象
public Class<? super T> getSuperclass()
- 返回Class对象所对应的类的"包.类名"形式的全名
public String getName()
- 返回一个包含所有声明的字段的数组,包括私有、受保护、默认和公共字段
public Field[] getDeclaredFields()
- 返回一个包含所有公共方法的数组,包括继承的方法
public Method[] getMethods()
- 返回一个包含所有公共构造函数的数组
public Constructor<?>[] getConstructors()
- 返回一个包含该类实现的接口的Class对象数组
public Class<?>[] getInterfaces()
- 检查该类是否是接口
public boolean isInterface()
- 检查该类是否是枚举类型
public boolean isEnum()
- 检查该类是否是数组类型
public boolean isArray()
Executable类
Executable类存于java.lang.reflect.Executable中, 以下是常用的方法
- 返回表示方法或构造函数修饰符的整数。可以使用Modifier类的方法来解释这个整数,以获得修饰符的详细信息。
public int getModifiers()
- 返回方法或构造函数的名称。
public String getName()
- 返回表示方法或构造函数参数类型的Class对象数组。
public Class<?>[] getParameterTypes()
- 返回表示方法或构造函数泛型参数类型的Type对象数组。
public Type[] getGenericParameterTypes()
- 返回所有形参, 并存入数组Parameter[]中
public Parameter[] getParameters()
- 返回参数的个数
public int getParameterCount()
Constructor<T>类
存在于java.lang.reflect. Constructor<T>中
- 返回构造函数的名称。
public String getName()
- 使用指定的参数值来创建构造函数的新实例。
public T newInstance(Object... initargs)
- setAccessible 方法的作用是在需要绕过Java语言访问控制检查的情况下,允许对对象进行访问,即使它们通常是私有的或受保护的。这可以用于反射,以访问那些在正常情况下不可访问的类成员(字段、方法、构造函数等)。
public void setAccessible(boolean flag) throws SecurityException
Method类
存于java.lang.reflect.Method中
- 返回方法的名称。
public String getName()
- 返回方法的修饰符,可以使用Modifier类的方法来解释这个整数,以获得修饰符的详细信息。
public int getModifiers()
- 调用方法并传递给它指定的参数值。返回方法的结果,如果方法是静态方法,则 obj 参数可以为 null。
public Object invoke(Object obj, Object... args)
Field类
存于中
- 返回字段的名称。
public String getName()
- 返回表示字段类型的 Class 对象。
public Class<?> getType()
- 设置指定对象中字段的值为新值。
public void set(Object obj, Object value)
- 获取指定对象中字段的值。
public Object get(Object obj)
Parameter类
存于java.lang.reflect.Parameter中
- 返回参数的名称。如果 Java 编译器在编译时保留了参数名称(通过编译时选项 -parameters),则可以获取实际参数名称,否则将返回一个泛型名称,如 “arg0”。
public String getName()
- 返回参数的修饰符,可以使用 Modifier 类的方法来解释这个整数,以获得修饰符的详细信息。
public int getModifiers()
- 返回参数的参数化类型。这通常包括泛型类型信息,例如泛型类、泛型方法的类型参数等。
public Type getParameterizedType()
- 返回参数的类型的 Class 对象。
public Class<?> getType()
如下是详细的示例代码
这里的示例按顺序包括了查看类等名称, 并进行了相应的反射调用, 当然我是存于chapter18这个包下的
package chapter18;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
interface fly {
void fly();
}
class Person implements fly {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void getString() {
System.out.println(name + age);
}
@Override
public void fly() {
}
@Override
public String toString() {
return name + " " + age;
}
}
class Student extends Person {
}
public class Demo1801 {
public static void main(String[] args) throws Exception {
//查看部分
System.out.println("---------------------查看部分---------------");
//获取包+类名
Class<?> c1 = null;
Class<?> c2 = null;
Class<?> c3 = null;
//三种方式获取Class对象
c1 = Class.forName("chapter18.Person");
c2 = Person.class;
c3 = new Person().getClass();
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
//获取父类
Class<?> c4 = null;
c4 = Student.class;
System.out.println(c4.getSuperclass());
//获取接口
Class<?>[] list = c1.getInterfaces();
for (Class<?> c : list) {
System.out.println(c);
}
//获取构造方法
Constructor<?>[] conList = c1.getDeclaredConstructors();//建立构造器数组,用来存储构造方法
for (int i = 0; i < conList.length; i++) {
int modify = conList[i].getModifiers();//获取访问权限
String name = conList[i].getName();//获取方法名
System.out.println(Modifier.toString(modify) + " " + name);
Class<?> para[] = conList[i].getParameterTypes();//获取参数类型
for (Class<?> c : para) {
System.out.println(c.getName());
}
}
//获取方法
Method[] declaredMethod = c1.getDeclaredMethods();
for (Method method : declaredMethod) {
//如果想获取权限那些,和上面的构造方法获取方式一样
System.out.println(method);
}
//获取一个类的所有变量(成员)
Field[] declaredFields = c1.getDeclaredFields();
for (Field f: declaredFields) {
//如果想获取权限那些,和上面的构造方法的获取方式一致
System.out.println(f);
}
//调用部分
System.out.println("---------------------调用部分---------------------------");
//调用构造方法
Constructor<Person> constructor = (Constructor<Person>) c1.getConstructor(String.class, int.class);
System.out.println(constructor.newInstance("John",20));
//调用方法
Method method = c1.getMethod("getString");
method.invoke(new Person("H",1));
//访问数据成员
Field nameField = c1.getDeclaredField("name");
nameField.setAccessible(true); // 设置可访问私有字段
String nameValue = (String) nameField.get(new Person("M",10));
System.out.println("Name: " + nameValue);
Field ageField = c1.getDeclaredField("age");
ageField.setAccessible(true);
int ageValue = ageField.getInt(new Person("M",10));
System.out.println("Age: " + ageValue);
}
}