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