反射就是把java类中的各种成分映射成相应的java类。
Reflection 是 Java 被视为动态(或准动态)语言的关键,允许程序于执行期 Reflection APIs 取得任何已知名称之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于执行期生成instances、变更 fields 內容或唤起 methods。
Java的类反射所需要的类并不多,它们分别是:Class、Field、Constructor、Method、Object。
Class类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。
Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Constructor类则封装了反射类的构造方法。
Method类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Object类:每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
Java的类反射所需要的类并不多,它们分别是:Class、Field、Constructor、Method、Object。
Class类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。
Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Constructor类则封装了反射类的构造方法。
Method类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Object类:每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
1. 得到某个对象的属性:
package org.hi;
import java.lang.reflect.*;
public class FieldReflectTest {
public static void main(String[] args) throws Exception {
Person person = new Person(20, "Hi");
Class cls = person.getClass();
// 获得age属性,age为public
Field fieldAge = cls.getField("age");
int age = fieldAge.getInt(person);
System.out.println("person's age is " + age);
// 获得name属性,name为private
Field fieldName = cls.getDeclaredField("name");
// 取消java语言访问检查
fieldName.setAccessible(true);
String name = (String) fieldName.get(person);
System.out.println("person's name is " + name);
// 获得sex属性,sex为static
Field fieldSex = cls.getField("sex");
String sex = (String) fieldSex.get(person);
System.out.println("person's sex is " + sex);
// 设置age、name属性值
fieldAge.setInt(person, 25);
fieldName.set(person, "Hello");
System.out.println(person);
}
}
class Person {
public int age;
private String name;
public static String sex = "male";
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public String toString() {
return "Person[age : " + age + ", name : " + name + "]";
}
}
运行结果:
2. 执行某对象的方法:
package org.hi;
import java.lang.reflect.*;
public class MethodReflectTest {
public static void main(String[] args) throws Exception {
Class cls1 = Class.forName("java.lang.String");
// 获得String类的charAt方法
Method charAtMethod = cls1.getMethod("charAt", int.class);
char result = (Character)charAtMethod.invoke(new String("abc"), 2);
System.out.println(result);
// 获得构造方法
Constructor<String> constructor = cls1.getConstructor(StringBuffer.class);
String str = constructor.newInstance(new StringBuffer("hello, world!"));
System.out.println(str);
// 获得静态方法
Class cls2 = Class.forName("org.hi.Test");
Method mainMethod = cls2.getMethod("main", String[].class);
mainMethod.invoke(null, new Object[] {new String[] {"hello", "world!"}});
//mainMethod.invoke(null, (Object) new String[] {"hello", "world!"});
// 获得私有方法
Method printMethod = cls2.getDeclaredMethod("print");
printMethod.setAccessible(true);
printMethod.invoke(new Test());
}
}
class Test {
public static void main(String[] args) {
for (String arg : args) {
System.out.print(arg + " ");
}
System.out.println();
}
private void print() {
System.out.println("private method");
}
}
运行结果:
3. 数组:
package org.hi;
import java.lang.reflect.*;
public class ArrayReflectTest {
public static void main(String[] args) throws Exception {
int[] array = new int[] {1, 2, 3};
System.out.println(array.getClass().getSuperclass().getName());
int length = Array.getLength(array);
System.out.println("The length of array is " + length);
System.out.println("before change : " + Array.getInt(array, 1));
Array.setInt(array, 1, 4);
System.out.println("after change : " + Array.getInt(array, 1));
}
}
运行结果:
由结果可知:数组的父类为Object。