package com.reflect;
public class Person {
int id;
String name;
private Person() {}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
public void eat(int num) {
System.out.println(name + "吃了" + num + "斤饭!");
}
private void sleep(int hour){
System.out.println(name + "一天睡" + hour + "小时!");
}
}
package com.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
/*
反射:当一个字节码文件加载到内存的时候,java虚拟机会对该字节码文件进行解剖,;然后会创建一个Class对象,把字节码文件的
信息全部绑定到该Class对象中,我们就可以通过该Class对象设置对象的属性或调用对象的方法等操作;
注意:在反射技术中,一个类的任何成员都有对应的类来描述;比如成员变量对应的是Field类,方法对应的是Method类;
*/
public class Demo1 {
// 获取Class对象的三种方式
@Test
public void test1() throws Exception {
// 创建一个对象
Person person = new Person(11, "张三");
System.out.println(person);
// 获取Class对象的方式1:通过forName()方法获取
// 推荐使用方式1;
Class clazz1 = Class.forName("com.reflect.Person");
System.out.println("clazz1:" + clazz1);
// 获取Class对象的方式2:通过类名获取
Class clazz2 = Person.class;
System.out.println("clazz1==clazz2?" + (clazz1==clazz2)); // true
// 获取Class对象的方式3:通过对象获取
Class clazz3 = new Person(11, "张三").getClass();
System.out.println("clazz2==clazz3?" + (clazz2==clazz3)); // true
}
// 通过Class对象获取构造方法
@Test
public void test2() throws Exception {
// 获取对应的Class对象
Class clazz = Class.forName("com.reflect.Person");
// 通过class对象获取构造方法:获取公共的构造方法
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor);
}
// 通过class对象获取构造方法:私有的公共的都能获取到
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors){
System.out.println(constructor);
}
// 根据参数类型获取指定的构造方法:只能获取公共的构造方法
Constructor constructor = clazz.getConstructor(int.class, String.class);
// 根据获取到的构造方法对象创建实例对象
Person p = (Person) constructor.newInstance(22, "李四");
System.out.println(p);
// 根据参数类型获取指定的构造方法:获取私有的构造方法
Constructor declaredConstructor = clazz.getDeclaredConstructor(null);
// 暴力反射
declaredConstructor.setAccessible(true);
Person p2 = (Person)declaredConstructor.newInstance(null);
System.out.println(p2);
}
// 通过Class对象获取成员方法
@Test
public void test3() throws Exception {
// 获取对应的Class对象
Class clazz = Class.forName("com.reflect.Person");
// 获取对应的方法:只能获取公共的方法
Method[] methods = clazz.getMethods();
for (Method method : methods){
System.out.println(method);
}
System.out.println("--------------");
// 获取所有的方法,但是不包含父类的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method method : declaredMethods){
System.out.println(method);
}
System.out.println("-------------");
// 获取指定的方法;参数1:方法的名字;参数2:参数的类型;
Person pp = new Person(33, "王五");
Method method = clazz.getMethod("eat", int.class);
// 执行方法;参数1:方法的调用对象,如果是静态方法,此处不用写对象,写null就行;参数2:方法所需要的参数;
method.invoke(pp, 3);
// 获取私有的方法
Method declaredMethod = clazz.getDeclaredMethod("sleep", int.class);
// 暴力反射
declaredMethod.setAccessible(true);
declaredMethod.invoke(pp, 6);
}
// 通过Class对象获取成员变量
@Test
public void test4() throws Exception{
// 获取对应的Class对象
Class clazz = Class.forName("com.reflect.Person");
// 获取成员变量:获取公共的
Field[] fields = clazz.getFields();
for (Field field : fields){
System.out.println(field);
}
System.out.println("------------------");
// 获取所有的成员变量
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields){
System.out.println(field);
}
System.out.println("------------------");
// 获取指定的成员变量
Person person = new Person(55, "赵六");
Field field = clazz.getDeclaredField("id");
// 暴力反射,设置访问权限
field.setAccessible(true);
// 设置成员变量的值;参数1:成员变量所属的对象;参数2:成员变量的值;
field.set(person, 66);
System.out.println(person);
}
}