反射(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为。”这个概念常常会和内省(Introspection)混淆,以下是这两个术语在Wikipedia中的解释:
- 内省用于在运行时检测某个对象的类型和其包含的属性;
- 反射用于在运行时检测和修改某个对象的结构及其行为。
用一个例子运用反射:
package com.an.lx;
public class Person {
private String name;
private int age;
public Person(){System.out.println("Constructor function");}
public Person(String name ,int age)
{
this.name = name;
this.age = age;
System.out.println("Paramter Constructor function");
}
public String getName() {
System.out.println("getName()=======");
return name;
}
public void setName(String name) {
System.out.println("setName()=========");
this.name = name;
}
public int getAge() {
System.out.println("getAge()==========");
return age;
}
public void setAge(int age) {
System.out.println("setAge()===========");
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
反射测试用例:
package com.an.lx;
import java.lang.reflect.Constructor;
public class PersonTest {
public static void main(String[] args) throws ClassNotFoundException {
try {
//获得类的字节码
Class c = Class.forName("com.an.lx.Person");
//调用默认的构造函数
Constructor c1 = c.getDeclaredConstructor();
//创建类的实例
Person p = (Person) c1.newInstance();
//调用函数
p.setAge(11);
p.setName("sdf");
System.out.println(p.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
如果将默认的构造函数私有化,编译器将会出现以下异常。
将测试代码改为:
package com.an.lx;
import java.lang.reflect.Constructor;
public class PersonTest {
public static void main(String[] args) throws ClassNotFoundException {
try {
//获得类的字节码
Class c = Class.forName("com.an.lx.Person");
//调用默认的构造函数
Constructor c1 = c.getDeclaredConstructor();
//设置强力破解
c1.setAccessible(true);
//创建类的实例
Person p = (Person) c1.newInstance();
//调用函数
p.setAge(11);
p.setName("sdf");
System.out.println(p.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面用的是默认构造函数的方法,也可以生成有参数的函数。
package com.an.lx;
import java.lang.reflect.Constructor;
public class PersonTest2 {
public static void main(String[] args) {
try {
//获得类的字节码
Class c = Class.forName("com.an.lx.Person");
//调用有参数函数
Constructor c1 = c.getDeclaredConstructor(new Class[]{String.class,int.class});
//强力破解
c1.setAccessible(true);
//生成实例
Person p = (Person) c1.newInstance(new Object[]{"java",9});
System.out.println(p.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}