package day_7; public class Person { private String name; private String id; public Person(){} public Person(String name, String id) { super(); this.name = name; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
package day_7; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /* * 反射原理: * 首先吧java文件保存到本地硬盘xxx.java * 编译java文件,成.class文件 * 使用jvm,把class文件通过类加载器加载到内存中 * class文件在内存中通过Class类表示 * 当使用反射时候,首先需要获取该.java文件对应的.class文件在内存中的Class类,得到这个类就可以得到class文件所有内容,包括属性、构造方法、普通方法; * 得到Class类的三种方法: * 类名.class * 对象.getClass() * Class.forName("路径") * 属性对应类Field * 构造函数对应类Constructor * 普通方法类Method */ public class Reflect { public static void main(String[] args) throws ClassNotFoundException { //获取Class类 Class clazz1 = Person.class; Class clazz2 = new Person().getClass(); Class clazz3 = Class.forName("day_7.Person"); } @Test public void test1()throws Exception{ Class clazz = Class.forName("day_7.Person"); Person p =(Person) clazz.newInstance(); p.setName("tom"); System.out.println(p.getName()); } //操作有参数的构造方法 @Test public void test2()throws Exception{ //获取Class类对象 Class clazz = Class.forName("day_7.Person"); //获取有参构造器,注意这个方法传递的参数类型是class Constructor cs = clazz.getConstructor(String.class,String.class); //通过有参构造器获取实例 Person p = (Person) cs.newInstance("tom","5"); System.out.println(p.getId()+":"+p.getName()); } //操作属性 @Test public void test3()throws Exception{ Class clazz = Class.forName("day_7.Person"); Person p = (Person) clazz.newInstance(); //获取name属性的属性对象 Field f = clazz.getDeclaredField("name"); //设置可以操作私有属性 f.setAccessible(true); //设置属性值,第一个值是类实例,第二个值是属性的值 f.set(p, "killy"); System.out.println(p.getName()); } //操作普通方法 @Test public void test4()throws Exception{ Class clazz = Class.forName("day_7.Person"); Person p1 = (Person)clazz.newInstance(); Method m1 =clazz.getMethod("setName", String.class); //让setName()方法运行,第一个参数是实例,第二个参数是方法的参数值 //操作私有方法需要设置m1.setAccessiable(true); //操作静态方法也不需要实例,在invoke("null","city"); m1.invoke(p1, "youkl"); System.out.println(p1.getName()); } }