public Printer bind(final Printer sp1){
// Printer sp;
InvocationHandler i =new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println(method.getName()+"hahhahah");
method.invoke(sp1,args);
return null;
}
};
为啥子函数的参数要是FINAL的
------解决方案--------------------
原文地址
编译器规定,方法中的匿名内部类在使用方法内的局部变量的时候,局部变量必须由final关键字修饰
我们先来看GC工作原理,JVM中每个进程都会有多个根,每个static变量,方法参数,局部变量,当然这都是指引用类型. 基础类型是不能作为根的,根其实就是一个存储地址. GC在工作时先从根开始遍历它引用的对象并标记它们,如此递归到最末梢,所有根都遍历后,没有被标记到的对象说明没 有被引用,那么就是可以被回收的对象(有些对象有finalized方法,虽然没有引用,但JVM中有一个专门的队列引用它们直到finalized方法被执行后才从该队列中移除成为真正没有引用的对象,可以回收,)
但是在内部类的回调方法中,s既不可能是静态变量,也不是方法中的临时变量,也不是方法参数,它不可能作为根,在内部类 中也没有变量引用它,它的根在内部类外部的那个方法中,如果这时外面变量重指向其它对象,则这个对象就失去了引用, 可能被回收,而由于内部类回调方法大多数在其它线程中执行,可能还要在回收后还会继续访问它.这将是什么结果?
匿名内部类把需要访问的外部变量作为一个隐藏的字段,这样得到了一个变量的引用拷贝 ,使用final修饰符不仅会保持对象不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期。所以这才是final 变量和final参数的根本意义。