反射总结框架:
一.反射的认识:
1.反射的核心操作:Object
public final native Class<?> getClass(); //返回Class类。 Class反射核心类,描述其他的类结构
2.反射的三种实例化方式:
a.任意对象.getClass()
b.类名.class
c.使用Class类提供的静态方法:Class.forName(String className)
3.反射的用途:利用反射创建类的对象
public T newIntance throws InstantiationException,IllegalAccessException
4.反射与工厂设计模式
interface fruit{
public void eat();
}
class apple implements fruit
{
@Override
public void eat() {
System.out.println("吃苹果");
}
}
class orange implements fruit
{
@Override
public void eat() {
System.out.println("吃橘子");
}
}
class Factory{
private Factory() {}
public static fruit getIntance(String className)
{
fruit fr=null;
try {
Class<?> cls=Class.forName(className); //拿到类的Class对象
fr=(fruit)cls.newInstance(); //实例化对象
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fr;
}
}
二.反射中四大核心类
1.Class类:反射核心类
取得父类的信息:
取得类的包名:public Package getPackage();
取得父类的Class对象:public native Class<?super T>getSuperclass;
取得实现的父接口:public Class<?>[] getInterfaces();
2.Constructor类:反射调用构造。
a.Class类提供的newInstance()方法默认调用无参构造。
b.Class类中getConstructor方法取得类中构造方法:
public Constructor <T> getConstructor(Class<?>... parameterTypes)
c.取得类中所有构造:
public Constructor<?>[] getConstructors() throws SecurityExce[tion
实例:
//取得class对象
Class<MyClass> cls=MyClass.class;
//取得Constructor对象
Constructor<MyClass> con=cls.getConstructor(String.class,Integer.class);
//调用Constructor对象的newInstance()
MyClass myClass=con.newInstance("holle",23);
3.Method类:反射调用普通方法。
取得全部普通方法(返回的是Method的对象):
public Method[] getMethods() throws SecurityException; //返回本类及父类的所有普通方法
public Method[] getDeclaredMethods(); //返回本类的所有方法
取得指定普通方法(返回的是Method的对象):
public Method getMethod(方法名,方法参数); //返回本类及父类的所有指定方法
public Method getDeclareMethod(方法名,方法参数); //返回本类的指定方法
调用(Method提供):
public Object incoke(类的实例化对象,方法具体参数)
使用Method类方法的步骤:
取得Class对象:
Class<MyClass> cls=MyClass.class;
取得Constructor对象:
Constructor<MyClass> constructor=cls.getDeclaredConstructor(String.class);
创建实例化对象:
MyClass myClass=constructor.newInstance("holle");
取得指定方法名称的方法:
Method method=cls.getMethod("setAge", Integer.class);
method.invoke(myClass, 12);
4.Field类:反射调用类中的属性。
取得类中所有属性:
public Field[] getFields(); //返回本类及父类所有属性
public Field[] getDeclaredFields(); //返回本类所有属性
取得类中指定属性;
public Field getField(属性名); //返回本类及父类所有属性
public Field getDeclaredField(属性名); //返回本类所有属性
调用(Field类):
设置属性内容:public void set(具体类的实例化对象,属性值)
取得属性内容:public Object get(具体实例化对象)
取得属性类型:
Field.getType()
取得属性类型:
public Class<?> getType();
取得属性的步骤:
//取得class对象
Class<MyClass> cls=MyClass.class;
//具体实例化对象
MyClass myClass=cls.newInstance();
//取得Field对象
Field filed=cls.getField("integer");
//设置以及取得属性
filed.set(myClass,23);
Object object=filed.get(myClass);
System.out.println(object);
反射四核心类的继承关系:
三.ClassLoader类加载器:
1.概念:
JVM定义把类加载阶段中的“通过类的全名称获取此类的二进制字节流”这种操作的实现模板叫类加载器。
查看类加载器:
public ClassLoader getClassLoader();
2.类加载器分类:
(1)Bootstrap(启动类加载器):使用C++实现,是JVM自身的一部分;启动类加载器负责加载存放于 <JAVA_HOME>\lib目录中能被JVM识别.(仅按照文件名识别,rt.jar).
(2)ExtClassLoader(扩展类加载器):负责加载<JAVA_HOME>\lib\ext目录中的类库;使用java语言实现,可以在程序中直接使用。
(3)AppClassLoader(应用程序类加载器):负责加载ClassPath的类库;如果在程序中没有定义类加载器,则此类加载器就是程序默认的类加载器。
(4)自定义类加载器:extends ClassLoader
3.双亲委派模型:
上图为类加载器之间的层次关系。
类加载器的工作流程:
如果一个类加载器收到了类加载请求,它首先不会自己去加载这个类,而是把请求委派给父类加载器完成,只有当父类加载器无法完成这个请求时,自类加载器才回去尝试加载。
双亲委派模型的作用:
主要保证java稳定运行。(基础类库不会被其他自定义类所影响,Object类,无论哪个类加载Object类,最终都是委派给启动类加载器加载)Object类在程序的各种类加载环境都是同一个类。
四.反射与代理设计模式:
动态代理设计模式:
1.传统代理与动态代理:
传统代理:
一个接口+两个实现
动态代理(Spring默认设计模式):基于接口,利用反射实现
一个接口+一个真实业务+通用代理类
示例:
/*
* 动态代理实现的表示接口,只有实现此接口才具备动态代理的功能
*/
interface InvocationHandler
{
/*
* invoke表示的是调用执行的方法,但是所有的代理类返回给用户的接口对象都属于代理对象
* 当用户执行接口方法的时候所调用的实例化对象就是该代理主题动态创建的一个接口对象
* proxy表示被代理的对象信息
* method返回的是被调用的方法对象,取得method对象则意味着可以使用invoke()反射调用方法。
* args方法接收的参数
* 方法的返回值
* Throwable 可能产生的异常
*/
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
/*
* 动态代理设计实现
*/
interface ISubject{ //核心操作接口
public void eat(String msg,int num); //吃饭是核心业务
}
class RealSubject implements ISubject{
@Override
public void eat(String msg, int num) {
System.out.println("我要吃"+num+"分量的"+msg);
}
}
/*
* 动态代理类
*/
class ProxySubject implements InvocationHandler, java.lang.reflect.InvocationHandler
{
//绑定任意接口对象,使用Object描述
private Object target;
/*
* 实现真实对象的绑定处理,同时返回代理对象
* 返回一个代理对象(这个对象是根据接口定义动态创建生成的代理对象)
*/
public Object Binder(Object target)
{
//保存真实主题
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public void preHnadle()
{
System.out.println("ProxySubject方法处理前");
}
public void afterHandle()
{
System.out.println("ProxySubject方法处理后");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.preHnadle();
//反射调用方法
Object object=method.invoke(this.target, args);
this.afterHandle();
return object;
}
}