反射原理
得到一个对象不通过New的方式创建
1.首先需要把Java文件保存到本地硬盘.Java
2.编译Java文件,成.class文件
3.使用JVM,把class文件通过类加载加载带内存中
4.万事万物皆对象,class文件在内存中用Class内表示
5.当使用反射时,首先要获取内存中的Class类,得到这个类之后,就可以得到class文件里面的所有内容(包括属性、构造方法、普通方法)
属性可以通过一个类来表示 Filed
普通方法可以通过一个类来表示 Constructor
构造方法可以通过一个类来表示 Method
反射使用
如果得到Class类,可以得到这个类中的所有内容 属性,普通方法,构造方法
得到Class类的三种方式:
(1)类名.class
(2)对象.getClass
(3)使用Class.forName(“类路径”)
一、使用反射得到一个对象。
1.建一个Person类
public class Person{ private String name; private int id; public Person(String name, int id) { this.name = name; this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Person() { } }
2.写Test
(1)使用反射操作无参构造方法
/*使用反射操作无参构造方法*/ @Test public void Test1() throws Exception{ /*得到Class*/ Class c3 = Class.forName("Pojo.Person"); /*获取实例*/ Person p = (Person)c3.newInstance(); p.setName("张三"); System.out.println(p.getName()); }
(2)使用反射操作有参构造方法
/*使用反射操作有参数的构造方法*/ @Test public void Test2() throws Exception{ /*得到Class*/ Class c = Class.forName("Pojo.Person"); /*获取有参构造器 参数里面传入方法里面的参数类型,使用的是class传递*/ Constructor cs = c.getConstructor(String.class,int.class); /*通过有参的构造器得到对象,并且传入参数*/ Person p = (Person)cs.newInstance("lisi",18); System.out.println(p); } }
二、使用反射操作类里面的属性
@Test public void Test3() throws Exception{ /*得到Class*/ Class c = Class.forName("Pojo.Person"); /*通过Class创建对象*/ Person p = (Person)c.newInstance(); /*得到一种属性,参数是属性的名称*/ Field f = c.getDeclaredField("id"); /*表示得到所有属性*/ c.getDeclaredFields(); /*设置可以操作私有属性 因为不让直接操作私有属性*/ f.setAccessible(true); /*第一个参数为对象,第二个参数为值 属性调用方法来给对象中的该属性赋值*/ f.set(p,18); /*通过属性调用对象,来得到对象的属性*/ System.out.println(f.get(p)); }
三、操作普通方法
@Test /*操作普通方法*/ public void Test4() throws Exception{ /*得到Class*/ Class c = Class.forName("Pojo.Person"); /*通过Class创建对象*/ Person p = (Person)c.newInstance(); /*得到普通方法,第一个参数为需要得到的方法名,第二个为方法参数的类型*/ Method method = c.getDeclaredMethod("setName", String.class); /*得到所有方法*/ Method[] method1 = c.getDeclaredMethods(); /*调用方法,第一个参数为对象,第二个参数为需设置的值*/ method.invoke(p,"zhangsan"); System.out.println(p.getName()); }
四、当操作的是一个静态方法的时候,因为静态方法调用的方式是 类名.方法名 不需要实例。所以使用反射操作静态方法的时候也是不需要实例的。
method.invoke(null,"lala");