1、反射机制
反射机制允许程序在执行的过程中通过Reflection API获取任意一个类的内部信息,并能够操作它的属性及方法。2、反射的简单认识
2.1 通过反射生成对象的实例(简单Java类Person)
Class personClass = Person.class //创建运行时类的对象
Person person = (Person)personClass.newInstance(); //创建Person对象的实例
2.2 通过反射生成实例并调用对象属性
*调用公有的属性
Filed name = personClass.getField("name"); // 获取public类型属性
name.set("zy");
*调用私有的属性
此时如果使用getField()调用报异常
java.lang.NoSuchFieldException
: name
如果没有name.setAccessiable(true)报异 访问权限非法常
java.lang.IllegalAccessException
:
Filed name = personClass.getDeclaredField("name"); //获取私有属性
name.setAccessiable(true); //将该属性设置为可访问的
name.set(person,"zy");
2.2 通过反射的生成实例并调用对象的方法
Method methodName = personClass.getMethod("MethodName"); //获取方法名为MethodName方法,没有带参数
methodName.invoke(person);
Method methodName = personClass.getMethod("MethodName",String.class); //带参数
methodName.invoke(person,"computer");
3、Class是反射的源头
3.1 反射机制
3.2 关于Class
一个.java类,通过javac.exe生成.class文件,然后通过java.exe将此.class文件加载(使用JVM类加载器)到内存中,此时这个被加载到内存中的.class文件就是一个运行时类。而这个运行时类本身就是一个Class的对象。每个运行时类只加载一次
3.3 创建Class类实例的方法(4种)
3.3.1 通过运行时类本身创建Class类的实例,调用class属性
Class personClass = Person.class;
3.3.2 通过运行时类的引用调用getClass()方法
Person person = new Person();
Class personClass = person.getClass();
3.3.2 通过Class类的静态方法forName()
String className = "com.relection.domain.Person";
Class personClass = Class.forName(className ); //动态的创建对象,可以根据用户传来的类名进行创建
Person person = (Person)personClass.newInstance();//创建Person的实例
3.3.4 通过类的加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class personClass4 = classLoader.loadClass("com.relection.domain.Person");
Person person2 = (Person) personClass4.newInstance();
4、类的加载器
类的加载器用来把类(class)加载进内存中。
java类的加载过程
java虚拟机的类加载器的种类
引导类加载器,用来加载核心类库,无法直接获取
扩展类加载器
系统类加载器
5、类加载器读取文件
ClassLoader loader = this.getClass().getClassLoader();
InputStream is = loader.getResourceAsStream("info.properties");
Properties p = new Properties();
p.load(is);
String userName = p.getProperty("username");
String password = p.getProperty("password");
6、通过类的反射获取类本身的信息
6.1 获取类的方法
6.2 获取类的属性及其权限
6.3 获取类的父类
6.4 获取已经实现的接口
6.5 获取父类的泛型
6.6 获取类的注解
7.反射的应用
7.1 Dao工厂
7.2 动态代理
代理类要实现InvocationHandler接口
public class QualityHandler implements InvocationHandler {
Object target; //声明被代理类对象的引用
public QualityHandler(Object obj){
target = obj;
}
public Object createProxy(Object target){
//此类加载器需要和目标对象的相同
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object object = method.invoke(target, args);
System.out.println("服装质量安全检查");
return object;
}
}