57.什么是反射?
反射本质上来说就是可以在运行时期,动态的获取类的信息以及动态的执行对象方法的过程
58.什么是 java 序列化?什么情况下需要序列化?
序列化:将 Java 对象转换成字节流的过程。
反序列化:将字节流转换成 Java 对象的过程。
情况:当 Java 对象需要在网络上传输 或者 持久化存储到文件中时,就需要对 Java 对象进行序列化处理
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 测试序列化,反序列化
*/
public class TestSerializable implements Serializable {
private static final long serialVersionUID = 5887391604554532906L;
private int id;
private String name;
public TestSerializable(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "TestSerializable [id=" + id + ", name=" + name + "]";
}
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("TestSerializable.obj"));
oos.writeObject("测试序列化");
oos.writeObject(618);
TestSerializable test = new TestSerializable(1, "ConstXiong");
oos.writeObject(test);
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("TestSerializable.obj"));
System.out.println((String)ois.readObject());
System.out.println((Integer)ois.readObject());
System.out.println((TestSerializable)ois.readObject());
}
}
59.动态代理是什么?有哪些应用?
动态代理:当想要给实现了某个接口的类中的方法,加一些额外的处理。
比如说加日志,加事务等。可以给这个类创建一个代理,故名思议就是创建一个新的类,这个类不仅包含原来类方法的功能,而且还在原来的基础上添加了额外处理的新类。
这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,扩展性强。
应用:Spring的AOP,加日志。
60.怎么实现动态代理?
实现方式:2种,分别为JDK的实现(基于接口的动态代理)和CGlib的实现(基于子类的动态代理)
既然是基于接口的动态代理,那么子类必须实现某个接口。所以我们创建接口和基于接口的子类
/**
* 接口
*/
public interface IProduncer {
public void saleProduct(float money);
public void afterService(float money);
}
/**
* 基于接口的子类
*/
public class Producer implements IProduncer{
public void saleProduct(float money){
System.out.println ("销售产品,并拿到钱"+money);
}
public void afterService(float money){
System.out.println ("提供售后服务,并拿到钱"+money);
}
}
/**
* JDK动态代理的实现
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer ();
/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码的基础上对方法进行增强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
* 基于接口的动态代理:
* 设计的类:Proxy
* 提供者:JDK官方
* 如何创建代理对象
* 使用Proxy类中的newProxtInstance方法
* 创建代理对象的要求:
* 被代理类最少实现一个接口,如果没有则不能使用
* newProxyInstance方法的参数:
* ClassLoader:类加载器
* 它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法
* Class[]:字节码数组
* 它是用于让代理对象和被代理对象有相同的方法。固定写法
* InvocetionHandler:用于提供增强的代码
* 它是让我们写如何代理。我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的
* 此接口的实现类都是谁用谁写
*/
IProduncer proxyProducer = (IProduncer) Proxy.newProxyInstance (producer.getClass ( ).getClassLoader ( ),
producer.getClass ( ).getInterfaces ( ),
new InvocationHandler () {
/**
* 执行被代理对象的任何接口方法都会经过该方法
* 方法参数的含义:
* @param proxy 代理对象的引用
* @param method 当前执行的方法
* @param args 当前执行方法所需的参数
* @return 和被代理对象方法有相同的返回值
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//提供增强的代买
Object returnVlaue = null;
//1获取方法执行的参数
Float money = (Float) args[0];
//2判断当前方法是不是销售
if("saleProduct".equals (method.getName ())){
//被代理的方法增强。
returnVlaue = method.invoke (producer, money*0.8f);
}
return returnVlaue;
}
});
proxyProducer.saleProduct (10000f);
}
}
/**
* 子类
*/
public class Producer {
public void saleProduct(float money){
System.out.println ("销售产品,并拿到钱"+money);
}
public void afterService(float money){
System.out.println ("提供售后服务,并拿到钱"+money);
}
}
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer ();
/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码的基础上对方法进行增强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
* 基于子类的动态代理:
* 设计的类:Emhancer
* 提供者:第三方cglib库
* 如何创建代理对象
* 使用Enhancer中的create方法
* 创建代理对象的要求:
* 被代理类不能是最终类
* create方法的参数:
* Class:字节码
* 它是用于指定被代理对象的字节码
* callback:用于提供增强的
* 我们一般写的都是该接口的子接口实现类:MethodInterceptor
*
*
*/
Producer cglibProducer = (Producer) Enhancer.create (producer.getClass (), new MethodInterceptor ( ) {
/**
*
* @param proxy
* @param method
* @param args
* @param methodProxy:当前执行方法的代理对象
* @return
* @throws Throwable
*/
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//提供增强的代买
Object returnVlaue = null;
//1获取方法执行的参数
Float money = (Float) args[0];
//2判断当前方法是不是销售
if("saleProduct".equals (method.getName ())){
returnVlaue = method.invoke (producer, money*0.8f);
}
return returnVlaue;
}
});
cglibProducer.saleProduct (10000);
}
}
比较 | 子类 | 接口 |
---|---|---|
设计的类 | Enhancer | Proxy |
提供者 | Cglib | JDK |
代理对象的创建 | Enhance.creat方法 | Proxy的newProxyInstance方法 |
代理对象创建时所需的参数 | 代理对象子类的字节码,callback接口的增强类(MethodInterceptor()) | 代理对象的类加载器,代理对象接口,InvocetionHandler增强类 |
invoke参数 | 代理对象子类,方法的参数 |