认识反射机制
认识反射
- 反射指的是对象的反向处理。根据对象倒推类的组成
- 反射核心处理在于Object类的方法
取得类的Class对象
- public final native class<?> getclass();
Class类描述的各个类的组成(构造方法、普通方法、普通属性)
Class对象的三种实例化对象
- 任何一个类的Class对象由JVM加载类后产生(JVM中全局唯一),用户只能调用指定方法来取得该对象
- 任何类的对象可以通过调用Object类提供的getClass()取得该类的Class对象
- "类名称.Class"可以直接根据具体类来取得其Class对象
- 调用Class类的静态方法Class.forName(String className)传入类的全名称来取得其Class对象
- 取得一个类的Class对象1后:可以通过反射实例化对象
反射与类操作
- 反射取得父类、父接口信息
取得类的包名称
- public Package getPackage()
取得父类的Class对象- public native Class< ? super T> getSuperClass();
取得实现的父接口- public Class<?>[] getInterfaaces();
- 反射调用类中构造方法–Constructor(描述类中构造方法)
取得类中指定参数类型的构造
只能取得public权限的构造方法
- public Constructor getConstructor(Class<?>… parameterTypes)
能取得所有权限的构造方法
- public Constructor getDeclaredConstructor(Class<?>… parameterTypes)
取得类中所有构造方法
只能取得public权限的构造方法
- public Constructor<?>[] getConstructors() throws SecurityException
能取得所有权限的构造方法
- public Constructor<?>[] getDeclaredConstructors() throws SecurityException
Constructor类提供了实例化对象的方法
可以调用类中有参构造
- public T newInstance(Object … initargs)
- 反射调用类中普通方法
取得类中指定名称的普通方法
- public Method getMethod(String name, Class<?>… parameterTypes)
- public Method getDeclaredMethod(String name, Class<?>… parameterTypes)
取得类中全部普通方法
取得本类及父类所有public方法
- public Method[] getMethods() throws SecurityException
取得本类的所有权限普通方法
- public Method[] getDeclareMethods() throws SecurityException
Method类提供调用类中普通方法的API
- public Object invoke(Object obj, Object… args)
- 反射调用类中的属性Field
取得类中指定名称属性
本类及父类
- public Field getField(String name)
本类
- public Method getDeclaredMethod(String name, Class<?.. parameterTypes)
取得类中全部普通属性
取得本类及父类所有public属性
- public Field[] getFields()
取得本类全部普通属性,包括私有属性
- public Field[] getDeclaredFields()
设置属性
- public void set(Object obj, Object value)
取得属性
- public Object get(Object obj)
- 动态设置封装
Constructor、Method、Field类都是AccessibleObject的子类
动态设置封装—在本次JVM进程中有效,且只能通过反射调用
- public void setAccessible(boolean flag) throws SecurityException
类加载器
-
概念:通过一个类的全名称来获取此类的二进制字节流,实现这个操作的代码模块称为类加载器。
-
JDK中内置的三大类加载器
Bootstarp(启动类加载器):
- 使用C++实现,是JVM的一部分,其他所有类加载器均使用Java实现。
- 负责将存放在<JAVA_HOME>\bin目录下的能被JVM识别的类库(rt.jar-存放了Java所有基础类库,java.lang,java.util)加载到JVM中。
- 启动类加载器无法被JAVA程序直接引用
ExtClassLoader(扩展类加载器)
- 使用Java实现,并且可以被Java程序直接引用
- 加载Java_Home\lib\ext目录下能被识别的类库。
AppClassLoader(应用程序类加载器)
- 负责加载用户路径(classPath)上指定的类库
- 如果应用程序中没有自定义类加载器,则此加载器就是Java程序中默认的类加载器。
- 类加载器双亲委派模型-JDK1.2引入
- 定义:JDK内置的三种类加载器与用户自定义类加载器之间的关系称为类加载器的双亲委派模型。要求除了顶层的父类加载器外,其余的类加载器都应有自己的父类加载器。
- 执行流程:如果一个类加载器收到一个类加载请求,首先它不会自己去尝试加载此类。而是把类加载请求委托给父类加载器去完成,每一个层次类加载器均是如此。
- 意义:只有当父类加载器无法完成加载请求时(在自己搜索范围内没有找到此类),子加载器才会尝试自己去加载。
- 双亲委派模型保证了Java程序稳定运行。Java中基础类库一定由顶层BootStrap类加载器加载,因此,诸如object等核心类在各种类加载器环境下都是同一个类。
- 每个类的使用需要在路径中加载文件,加载时路径地址有相同的可能,采用双亲委派模型保证了基础核心自带类库如Object类,只能采用其自带的类,而不是使用者自己定义的同路径同名称的类
- 比较两个类相等的前提:这两个类必须是由同一个类加载器加载的前提下才有意义。