a
只能是最终的。 为什么? 我怎样才能重新分配a
中onClick()
方法中没有保持它作为私有成员?private void f(Button b, final int a){ b.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int b = a*5; } }); }
单击后如何返回
5 * a
? 我的意思是,private void f(Button b, final int a){ b.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int b = a*5; return b; // but return type is void } }); }
#1楼
也许这个把戏给你一个主意
Boolean var= new anonymousClass(){
private String myVar; //String for example
@Overriden public Boolean method(int i){
//use myVar and i
}
public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar("Hello").method(3);
#2楼
之所以只将访问限制在局部最终变量上,是因为如果所有局部变量都可以访问,则首先需要将它们复制到一个单独的部分,内部类可以访问这些部分并维护它们的多个副本。可变的局部变量可能会导致数据不一致。 最终变量是不可变的,因此复制到它们的任何数量都不会对数据的一致性产生任何影响。
#3楼
当在方法主体中定义匿名内部类时,可以从内部类中访问在该方法范围内声明为final的所有变量。 对于标量值,一旦将其赋值,最终变量的值就无法更改。 对于对象值,引用不能更改。 这允许Java编译器在运行时“捕获”变量的值,并将副本存储为内部类中的字段。 一旦外部方法终止并删除了其堆栈框架,原始变量就消失了,但是内部类的私有副本仍保留在该类自己的内存中。
( http://en.wikipedia.org/wiki/Final_%28Java%29 )
#4楼
由于Jon拥有实现细节的答案,另一个可能的答案是JVM不想处理已结束激活的记录中的写操作。
考虑一下用例,您的lambda而不是被应用,而是存储在某个地方并稍后运行。
我记得在进行此类修改时,您会在Smalltalk中筹集非法商店。
#5楼
有一个技巧可以允许匿名类更新外部作用域中的数据。
private void f(Button b, final int a) {
final int[] res = new int[1];
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
res[0] = a * 5;
}
});
// But at this point handler is most likely not executed yet!
// How should we now res[0] is ready?
}
但是,由于同步问题,此技巧不是很好。 如果稍后调用处理程序,则需要1)如果从不同线程调用了处理程序,则同步对res的访问2)需要具有某种标志或指示,表明res已更新
但是,如果立即在同一线程中调用匿名类,则此技巧行得通。 喜欢:
// ...
final int[] res = new int[1];
Runnable r = new Runnable() { public void run() { res[0] = 123; } };
r.run();
System.out.println(res[0]);
// ...
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3186798