整理下一些零碎到知识,想到啥写啥,主要供自己复习。
继承、组合、代理
他们三个有一些地方还算挺相似到,有时候会有一些容易混淆到地方。
继承:
先说Object吧,是所有类的父类,其包含的方法有:
- HashCode() 返回哈希码。
- toString() 返回字符串。
- equals() 判断对象地址与值是否相等,与==号等价,基本到数据类型里==比较值大小,在String类和基本数据类型的封装类如等等大部分类重写了该方法,只判断值是否相等,我们自己写的类里就是比较大小和地址。
- clone() 对象克隆。
- notify()启动线程。
- notifyAll()启动所有线程。
- waite()设置线程等待,与Thread.sleep有区别,waite释放排他锁,sleep不释放锁。
- finalize()设置对象被回首前进行操作。
- getClass()返回类对象。
子类继承父类后,具有父类的特性,父类实现对子类可见。修改父类,子类也必须做出修改,是高耦合的。不可在运行时改变
组合
就是在新类里new一个类出来,引用原类到方法。耦合度比较低,改变原类到实现不需要改变现有类代码。
代理
代理包括静态代理和动态代理。
静态代理
public interface Person {
void giveMoney();
}
class Student implements Person{
@Override
public void giveMoney() {
System.out.println("交书费50给老师");
}
}
class StudentProxy implements Person{
Student SU;
StudentProxy(Student SU){
this.SU=SU;
}
public void giveMoney() {
//交书费前发现50块钱原来掉到坑里过,脏了,不能直接给老师
System.out.println("我先换了一张新的50元");
SU.giveMoney();
//交了书费后
System.out.println("班长拿你的钱去洗了");
}
}
class Text{
public static void main(String[] args) {
Student student=new Student();
StudentProxy studentProxy=new StudentProxy(student);
studentProxy.giveMoney();
}
}
输出结果:
我先换了一张新的50元
交书费50给老师
班长拿你的钱去洗了
Process finished with exit code 0
代理即降低了耦合度,还可以在中间做很多事情,你并不需要知道到东西,班长在背后默默得贡献并不想让你知道,你只需要关心自己交了钱就是了。我们可以根据这个可以在这里面增加很多功能,并且不需要改变原类的代码,只需要改变代理类里到代码。上面的代码都是我们先编写好的,因为代理类需要实现和原类一样到接口,因此在实际开发里会存在很多代理类,接口增加方法时,原类和代理类都要维护。因此可以通过动态代理的方法解决上面到问题。
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class StudentProxy implements InvocationHandler {
Object student;
StudentProxy(Object student){
this.student=student;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("do something before");
method.invoke(student,args);
System.out.println("do something after");
return null;
}
}
class Text{
public static void main(String[] args) {
Persion2 student=new Student();
InvocationHandler studentProxy=new StudentProxy(student);
Persion2 stu= (Persion2) Proxy.newProxyInstance(studentProxy.getClass().getClassLoader(),student.getClass().getInterfaces(),studentProxy);
System.out.println(stu.getClass().getName());
stu.giveMoney();
}
结果:
com.sun.proxy.$Proxy0
do something before
交50块书费
do something after
Process finished with exit code 0
动态代理就不需要实现接口
CGlib实现动态代理
前面到两种方法实现代理都要求目标对象实现一个接口,而有时候目标对象没有实现接口时可以使用CGlib来实现动态代理,并且更加高效。
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibpProxy implements MethodInterceptor{
private Object student;
CglibpProxy(Object student){
this.student=student;
}
//给目标类创建一个代理对象
public Object getProxyInstance(){
//工具类
Enhancer enhancer=new Enhancer();
//设置父类
enhancer.setSuperclass(student.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("do something before");
Object stu=method.invoke(student,objects);
System.out.println("do something after");
return stu;
}
}
class Text22{
public static void main(String[] args) {
Student student=new Student();
Student student1=(Student) new CglibpProxy(student).getProxyInstance();
System.out.println(student1.getClass().getName());
student1.giveMoney();
}
}
结果:
Prox.Student$$EnhancerByCGLIB$$f06154c
do something before
交50块书费
do something after
Process finished with exit code 0