a can only be final here. Why? How can I reassign a in onClick() method without keeping it as private member? private void f(Button b, final int a){ b.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int b = a*5; } }); } How can I return the 5 * a when it clicked? I mean, 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 } }); }
当前回答
要理解这种限制的基本原理,请考虑以下程序:
public class Program {
interface Interface {
public void printInteger();
}
static Interface interfaceInstance = null;
static void initialize(int val) {
class Impl implements Interface {
@Override
public void printInteger() {
System.out.println(val);
}
}
interfaceInstance = new Impl();
}
public static void main(String[] args) {
initialize(12345);
interfaceInstance.printInteger();
}
}
The interfaceInstance remains in memory after the initialize method returns, but the parameter val does not. The JVM can’t access a local variable outside its scope, so Java makes the subsequent call to printInteger work by copying the value of val to an implicit field of the same name within interfaceInstance. The interfaceInstance is said to have captured the value of the local parameter. If the parameter weren’t final (or effectively final) its value could change, becoming out of sync with the captured value, potentially causing unintuitive behavior.
其他回答
试试这段代码,
创建数组列表并将值放入其中并返回:
private ArrayList f(Button b, final int a)
{
final ArrayList al = new ArrayList();
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
int b = a*5;
al.add(b);
}
});
return al;
}
Java内部类中的final变量[关于]
内部类只能使用
外部类引用 final局部变量来自范围外的引用类型(例如Object…) 值(原语)(例如int…)类型可以由最终引用类型包装。IntelliJ IDEA可以帮助您将其转换为一个元素数组
当编译器生成一个非静态嵌套(内部类)时-一个新类- <OuterClass>$<InnerClass>.class创建并将有界参数传递给构造函数[堆栈上的局部变量],它类似于闭包[Swift about]
Final变量是不能重新赋值的变量。最终引用变量仍然可以通过修改状态来更改
如果这是可能的,那就奇怪了,因为作为一个程序员,你可以做出这样的东西
//Not possible
private void foo() {
MyClass myClass = new MyClass(); //Case 1: myClass address is 1
int a = 5; //Case 2: a = 5
//just as an example
new Button().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
/*
myClass.something(); //<- what is the address - 1 or 2?
int b = a; //<- what is the value - 5 or 10 ?
//illusion that next changes are visible for Outer class
myClass = new MyClass();
a = 15;
*/
}
});
myClass = new MyClass(); //Case 1: myClass address is 2
int a = 10; //Case 2: a = 10
}
也许这个把戏能给你启发
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);
When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. For scalar values, once it has been assigned, the value of the final variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.
(http://en.wikipedia.org/wiki/Final_%28Java%29)
访问被限制为局部final变量的原因是,如果所有的局部变量都是可访问的,那么它们首先需要被复制到一个单独的部分,在那里内部类可以访问它们,并且维护可变局部变量的多个副本可能会导致数据不一致。而final变量是不可变的,因此任何数量的拷贝都不会对数据的一致性产生任何影响。
推荐文章
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?
- “java”、“javaw”和“javaws”之间有什么区别?
- 将Date对象转换为日历对象
- 在Java中保存最后N个元素的大小有限的队列
- 如何运行一个类从Jar不是主类在其清单文件