Java反射
反射概述
Java反射机制指的是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法。对于任意一个对象,都能够调用它的任意属性和方法,这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
反射常用类
- Class:
Class
类的实例表示正在运行的Java
应用程序中的类和接口。 - Constructor:关于类的单个构造方法的信息以及对它的权限访问。
- Field:Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。
- Method:Method 提供关于类或接口上单独某个方法的信息。
获取Class对象的方法
获取Class对象的的方法有以下几种:
类名.class
Class<Person> clazz = Person.class;
对象.getClass()
Person p1 = new Person();
Class clazz2 = p1.getClass();
Class.forName(全限定类名)
Class clazz3 = Class.forName("com.emhum.demo.Person");
- 使用类的加载器,ClassLoader(这种方式了解即可)
ClassLoader classLoader = PersonTest.class.getClassLoader();
Class clazz4 = classLoader.loadClass("com.emhum.demo.Person");
反射示例
定义Person类:
public class Person {
private String name;
public int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(String name) {
this.name = name;
}
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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void show() {
System.out.println("你好啊!");
}
public String showAddress(String address) {
System.out.println("我的地址是:" + address);
return address;
}
}
测试获取Person类的部分结构信息:
public class PersonTest {
//使用反射,对Person进行操作
@Test
public static void test1() throws Exception {
Class<Person> clazz = Person.class;
//通过反射,创建Person类的对象
Constructor<Person> cons = clazz.getConstructor(String.class, int.class);
/**
* newInstance():调用此方法,创建对应的运行时类的对象。
* 1.运行时类必须提供空参的构造器
* 2.空参的构造器的访问权限通常设置为public
*/
Person p = cons.newInstance("tom", 12);
System.out.println(p.toString());
//通过反射,调用对象指定的属性和方法
//调用属性
Field age = clazz.getDeclaredField("age");
age.set(p, 10);
System.out.println(p.toString());
//调用方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(p);
//通过反射,可以调用Person类的私有结构,比如:私有构造器,私有方法,私有属性。
//调用私有构造器
Constructor<Person> cons1 = clazz.getDeclaredConstructor(String.class);
//保证此构造器是可访问的
cons1.setAccessible(true);
Person p1 = cons1.newInstance("jerry");
System.out.println(p1);
//调用私有的属性
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(p1, "tomas");
System.out.println(p1);
//调用私有的方法
Method showAddress = clazz.getDeclaredMethod("showAddress", String.class);
showAddress.setAccessible(true);
showAddress.invoke(p1, "上海");
}
}