关键字final有什么用?
在下面的代码中,如果我从 EditText 中删除关键字 Final,我会在第 (6) 行中出现错误,其中我将 EditText 对象 (et) 传递给意图...我必须知道这里 Final 关键字的重要性...
final EditText et=(EditText)findViewById(R.id.t);
Button b=(Button)findViewById(R.id.b1);
b.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v)<br>
{
Intent on=new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+et.getText()));
startActivity(on);
}
});
In the below code if i remove the keyword final from EditText i am an getting error in the line (6) where i pass EditText object (et) to the intent...I have to knw the significance of final keyword here...
final EditText et=(EditText)findViewById(R.id.t);
Button b=(Button)findViewById(R.id.b1);
b.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v)<br>
{
Intent on=new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+et.getText()));
startActivity(on);
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Final本质上意味着变量
et
在任何时候都不会被重新分配并且将保留下来。这意味着内部类(例如您的侦听器)可以相信它不会被其他线程重新分配,这可能会导致各种麻烦。Final 还可以用于修改方法或类定义,这意味着该方法不能被子类覆盖,或者该类不能扩展。
Final essentially means that the variable
et
will not be reassigned at any point and will remain around. This means that inner classes, like your listener, can trust that it wont be reassigned by some other thread which could cause all kinds of trouble.final can also be used to modify a method or class definition, that would mean that the method can't be overriden by a subclass, or that the class cannot be extended.
这是因为你在这里使用了闭包。这意味着内部类使用入界类的上下文。要使用它,变量应该声明为final,以免被更改。
请参阅此处了解更多信息。
It is because you use closure here. It means that inner class uses the context of the inbounded one. To use it the variables should be declared final in order not to be changed.
See more here.
JAVA中“final”关键字的用途可以定义为三个层次:类、方法、变量
The purpose of “final” keyword in JAVA can be defined in three level are Class, Method, variable
Final 使得变量 et 只允许被赋值一次。它还更改变量的范围并允许函数 onClick 对 et 可见。如果没有final,et 在onClick 函数中不可见。
Final makes the variable et only allowed to be assigned once. It also changes the scope of the variable and allows the function onClick visibility to et. Without the final, et is not visible within the function onClick.
阅读本文了解所涉及的实现细节:
编辑:
原因是为了确保用户意识到闭包“关闭”变量而不是值。让我们假设不需要有最终的局部变量。然后我们可以编写如下代码
:你认为会是输出吗?如果你认为它会是“0 1 2”,那么你就错了,因为 Runnable 在“变量” i 上关闭,而不是在该时间点 i 的“值”,因此输出应该是“2 2 2”。可以采取什么措施来实现这里的预期行为?有两种解决方案:要么依靠用户了解闭包的工作原理,要么以某种方式在语言级别强制执行它。语言设计者已经采用了
JFTR,我并不是说第二个选项是“最好的”方法,只是在匿名内部类中使用之前将局部变量标记为 Final 是一个大问题。当然是我。:-)
Read this article to understand the implementation details involved:
EDIT:
The reason is to make sure that users realize that closures "close over" variables and not values. Let's suppose that there was no requirement of having final local variables. Then we could write code like:
What do you think would be the output? If you think it would be "0 1 2" you would be mistaken since the Runnable closes over the "variable" i and not the "value" of i at that point in time and hence the output would be "2 2 2". What can be done to achieve the expected behaviour here? Two solutions: either rely on the users to have an understanding of how closures work or somehow enforce it at the language level. And it is the second option with which the language designers have gone with.
JFTR, I'm not saying that the second option is "the" way to go, it's just that having local variables marked as final before being used in anonymous inner classes is a big deal breaker for me. Of course, YMMV. :-)
这是一个讨论
的链接
Final
关键字。根据规范(第 4.12.4 节):Here is a link which discusses the
final
keyword. According to the specification (section 4.12.4):它还有助于理解 Java 如何创建匿名内部类。 Java 如何实现该特定类。
Java 需要该变量是最终变量,因为编译器必须在编译时知道该对象的类型。然后,编译器将在匿名内部类实现中生成一个字段(在本例中为“et”)。
如果类型不是最终类型,编译器将如何确定如何构建内部类实现。基本上,通过将字段声明为 Final,您可以向 Java 编译器提供更多信息。
对编译器没有帮助的代码,不会编译你的匿名内部类:
...
通过上面的代码,Java编译器无法真正构建匿名内部类。
您的代码:
Final EditText et=(EditText)findViewById(R.id.t);
……
java 编译器将创建一个字节码类,它是您提供的内部类块的实现,可能如下所示。
您可以通过查找匿名字节码类 $1 并反编译该字节码文件来测试我提供的伪代码。
It also helps to understand how Java creates an anonymous inner class. How Java implements that particular class.
Java needs for that variable to be final because the compiler must know the type of that object at compile time. The compiler will then generate a field within the anonymous inner class implementation (in this case 'et').
If the type is not final, how would the compiler determine how to build the inner class implementation. Basically, by declaring the field final, you are giving the Java compiler more information.
Code that doesn't help the compiler, won't compile your anonymous inner class:
...
With the code above, the Java compiler cannot really build the anonymous inner class.
Your code:
final EditText et=(EditText)findViewById(R.id.t);
...
...
The java compiler will create a bytecode class, an implementation of that inner class block that you provided that might look like this.
You can test the pseudo code I provided by finding the anonymous bytecode class $1 and decompile that bytecode file.