Java中的反射
Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。
例如有如下Person
类
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name) {
System.out.println(name);
}
public Person(String name, int age) {
System.out.println(name + " " + age);
}
private void getName() {
System.out.println("Person.getName " + this.name);
}
}
获得 Class 类
第一种方式是通过Object
类的getClass()
方法;
Person person = new Person();
Class personClass = person.getClass();
第二种为Person.class
,第三种方式为Class.forName("com.mycompany.app.Person")
。
这样看起来第三种方式更好,只需要传入字符串即可,但是需要带上包名。
获得构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)
获取public
修饰, 指定参数类型所对应的构造方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
获取指定参数类型所对应的构造方法(包含私有的)
返回多个构造方法
public Constructor<?>[] getConstructors()
获取所有的 public 修饰的构造方法
public Constructor<?>[] getDeclaredConstructors()
获取所有的构造方法(包含私有的)
获取构造方法示例
public static void main(String[] args) {
Class personClass = null;
try {
personClass = Class.forName("com.mycompany.app.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Constructor<Person>[] personConstructors = personClass.getDeclaredConstructors();
for (Constructor personConstructor : personConstructors) {
System.out.println(personConstructor);
}
}
输出
public com.mycompany.app.Person()
public com.mycompany.app.Person(java.lang.String)
public com.mycompany.app.Person(java.lang.String,int)
获取变量与方法
返回一个成员变量
public Field getField(String name)
获取指定的 public 修饰的变量
public Field getDeclaredField(String name)
获取指定的任意变量(包含私有)
返回多个成员变量
public Field[] getFields()
获取所有 public 修饰的变量
public Field[] getDeclaredFields()
获取所有的变量 (包含私有)
返回获取一个方法:
public Method getMethod(String name, Class<?>... parameterTypes)
获取public
修饰的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
获取任意的方法,包含私有的
参数 1: name
要查找的方法名称; 参数 2: parameterTypes
该方法的参数类型
返回获取多个方法:
public Method[] getMethods()
获取本类与父类中所有public
修饰的方法
public Method[] getDeclaredMethods()
获取本类中所有的方法(包含私有的)
如下示例,使用反射给变量赋值并且调用特定方法。
public static void main(String[] args) throws NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class personClass = Class.forName("com.mycompany.app.Person");
Constructor<Person> personConstructor = personClass.getConstructor(String.class);
Field nameField = personClass.getDeclaredField("name");
Person person = personConstructor.newInstance("Jason");
nameField.setAccessible(true);
nameField.set(person, "leevare");
Method method = personClass.getDeclaredMethod("getName");
method.setAccessible(true);
method.invoke(person, null);
System.out.println(person);
}
输出
Jason
Person.getName leevare
com.mycompany.app.Person@38082d64
这里将nameFiled
和method
通过setAccessible
设置值为true
,可以取消 Java 语言访问检查,否则调用或者给private
的内容赋值会报错。方法可以通过invoke
来进行调用,第一个参数为实例对象,之后为方法的参数。
使用反射还可以跳过泛型的约束,例如如下示例
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
ArrayList<String> list = new ArrayList<>();
list.add("word");
Class listClass = Class.forName("java.util.ArrayList");
Method method = listClass.getMethod("add", Object.class);
method.invoke(list, 132);
System.out.println(list);
}
本来list
只可以添加String
类型的值,但是使用反射之后,可以向其中添加任意类型的值,上述输出结果为[word, 132]
。
本文整理自:http://www.cnblogs.com/ginb/p/7118078.html
- 本博客所有文章除特别声明外,均可转载和分享,转载请注明出处!
- 本文地址:https://www.leevii.com/?p=1734