Web开发——反射
一、 简介:反射是框架设计的灵魂。将类的各个组成部分封装为其它对象。可以在程序运行中操作这些对象,可以解耦并提高层序可扩展性。
二、 反射机制:java代码在计算机中要三个阶段
-
源代码阶段:我们写好“.java”源文件代码后不能立即运行,要通过 javac命令对文件进行编译,编译后在磁盘中生成“.class”字节码文件。此时文件还未进内存,对象还未生成。
-
Class类对象阶段:通过类加载器ClassLoader将字节码文件加载进内存。用Class对象来描述这些字节码文件中的信息(构造方法、成员变量等)
-
运行时阶段:通过new关键字来在内存中构建对象
三、Class
-
获取与设置成员变量:主要目的用来获取、设置成员变量的值。
-
获取所有变量:
考虑修饰符:public Field[] getFields()
不考虑修饰符:public Field[] getDeclaredFields()
-
根据名称获取特定变量:
考虑修饰符:public Field getField()
不考虑修饰符:public Field getDeclaredField()
-
获取到变量对象Filed后可以用来设置、获取某个对象中该变量的值:
public class Test { public static void main(String[] args) throws Exception { Class<Person> pCLass = Person.class; Person person = new Person(); Field age = pCLass.getDeclaredField("age"); age.setAccessible(true); //暴力反射 age.set(person,2); //对private修饰的成员变量需要暴力反射忽略其权限 System.out.println("person.age:"+age.get(person)); } }
-
-
构建对象newInstance():利用Class生成实例对象
Person类有无参默认构造方法才行Class person = Person.class; Object p = person.newInstance(); System.out.println(p);
-
获取与设置成员方法:主要目的用来调用执行方法。
public class Test { public static void main(String[] args) throws Exception { Class personClass = Person.class; Person person = new Person(); Method eat = personClass.getMethod("eat",String.class);//获取特定方法,指明 eat.invoke(person,"饭.."); } }
-
加载字节码文件的三种方法:
- Class.forName(“全类名”)
- 类名.class
- 对象.getClass() -
反射的应用
-
不改变类的任何代码,可以创建任意类的对象,调用任意方法。
在配置文件中写好类名与要调用的方法名。
package Day_3_20; public class Person { public void sleep(){ System.out.println("sleep...."); } }
利用反射来生成配置文件中指定的类对象并调用其方法。
public class Test { public static void main(String[] args) throws Exception { InputStream reader = Test.class.getClassLoader().getResourceAsStream("pro.properties"); Properties pre = new Properties(); pre.load(reader); String className = pre.getProperty("className"); String methodName = pre.getProperty("methodName"); Class<?> aClass = Class.forName(className); Object obj = aClass.newInstance(); Method method = aClass.getMethod(methodName); method.invoke(obj); } } ```
-