反射 动态代理 线程池
反射 动态获取类的字节码文件,并对其进行抽象
通过反射可以获取一个类的全部方法和属性,然后进行调用。
反射与类之间抽象的理解:Class 将字节码对象进行抽象 出现了:
1.属性:表示字节码文件的属性的属性:private Field field;
2.属性:表示字节码文件的普通方法的属性:private Mathod method;
3.属性:表示字节码文件的构造方法:private Constructor con;
[外链图片转存失败(img-NYdDgqXU-1568049804584)(imgss\cc.png)]
字节码文件之间可以越过new 创建对象
注意:Class的父类是Object
-
通过反射创建对象?
1.获取字节码文件对象
2.通过字节码文件对象获取对应的实例对象
3.给属性赋值
4.调用方法
步骤:
1.获取字节码文件对象
1.类对象:getClass();//这里的对象也是new出来的,不适合
2.Person.class;?
3.Class.forName("包名加类名");//先比2更灵活不需要知道类名
2.通过字节码文件对象获取对应的实例对象
1.普通的方式:Person person = new Person()
2.通过反射创建
- 无参:字节码文件对象调用newInstance();//newInstance()方法内部调用了无参构造
- 有参:先拿到构造方法的对象
Constructor constructor = cls.getConstructor(String.class,int.class);//参数是可变的。在字节码文件中穿的是字节码文件类型,而name和age是值
object = constructor.newInstance("bingbing",18);
3.给属性赋值
1.name是public
Field field1 = class.getField("name");
2.name是private
//给对象给属性赋值
Field field =class1.getDeclaredField("name");
field1.set(object, "bing");
// 将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
field.setAccessible(true);
//赋值
field1.set(object, "bing");
4.调用方法非静态
调用非静态无参:
//通过字节码文件得到反射方法
Method method = cla.getMethod(“show”);
//调用方法,通过调用invoke方法实现
method.invoke(object);
调用非静态有参
//先得到有参的构造方法
Constructor<?> constructor = cla.getConstructor(String.class,int.class);
Object object = constructor.newInstance("bingibn",10);
//通过反射得到方法
Method method = cla.getMethod("callPhone",String.class);
//调用方法,通过调用invoke方法实现
method.invoke(object,"110");
5.调用方法静态
调用静态有参:
//通过反射得到方法:Method method = cla.getMethod("run",int.class);
//调用方法
method.invoke(null,11);
动态代理 (设计模式)
静态代理
1.作用:根据OCP(对扩展开发,对修改关闭)的原则,在不改变原来类的基础上,给这个类增加新的功能
2.缺点:代理对象要保证和目标对象实现同样的功能,在维护的收两个对象都要维护,而且代理对象实现的接口是死的。这时如果要给想实现不同功能的多个目标对象添加代理对象的话,要添加很多个类
动态代理:在程序运行时运用反射机制动态创建而成
动态生成代理对象的方法–通过JDK内置的java.lang.reflect.Proxy动态代理类完成代理对象的创建
1.参数一:这里代表类加载器,代理类的类加载器要与目标类的类加载器一致,类加载器用来装载内存中的字节码文件
2.参数二:代理类于目标类实现的接口必须是相同的,即指定给代理类的接口,目标必须实现了
3.参数三:代理类的类构造器生成的对象–注意:指定给构造方法的参数要使用Object
TestInter object = (TestEat)Proxy.newProxyInstance(testEat.getClass().getClassLoader(),new Class[]{TestIner.class},new Agent(testIner));
工厂类:
//创建一个工厂类---用于创建代理对象
public class TestFactory {
//工厂方法
public static TestInter getAgentFactory( final TestInter test) {
//final TestInter test = new Bingbing();
return (TestInter)Proxy.newProxyInstance(test.getClass().getClassLoader(), new Class[]{TestInter.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("扣一半房租做中介费");
// TODO Auto-generated method stub
//通过反射的方法调用具体对象的方法
Object object = method.invoke(test, args);
System.out.println("哈哈大笑");
return object;
}
});
}
}
线程池
创建线程池–Executors
1.newCachdThreadPool创建一个可缓存线程池,如果线程池的长度超过处理需要,可灵活回收线程,若无可回收,则新建线程
2.newFiledThreadPool创建一个定长线程池,可控制最大并发数,超过的线程会在队列中等待
3.newScheduledThreadPool创建一个单线程化的线程池,它只会唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO LIFO)
收,则新建线程
2.newFiledThreadPool创建一个定长线程池,可控制最大并发数,超过的线程会在队列中等待
3.newScheduledThreadPool创建一个单线程化的线程池,它只会唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO LIFO)