我发现一些Java ide有这样的规则,甚至在不询问用户的情况下就把事情做了。例如,简单地打开一个没有任何"final"关键字的文件,IDE就会到处插入一堆关键字,尤其是在变量上。
我的观点一直是:"如果IDE可以通过算法做到这一点,JVM也可以"
这个论点站得住脚吗?Java开发人员何时应该使用"final"关键字?每个可能是final的变量都应该这样声明吗?
谢谢!
我的观点一直是:"如果IDE可以通过算法做到这一点,jvm也可以"
这个论点站得住脚吗?
不。因为当IDE这样做时(我还没见过没有请求就默认这样做的,即使你可以显式地配置它来这样做),开发人员可以检查它是否真的是他们想要的决定。这个可以防止其他代码做违背开发人员意愿的事情。
如果在执行时只执行,那将破坏整个目的。如果我创建一个字段final
是为了防止其他代码修改它,那么如果其他代码试图修改它,我希望出现编译时错误。如果它只是留给JVM,我不能依赖代码而不是来修改它。
Java开发人员何时应该使用'final'关键字?
对于字段,当该字段在构造函数中初始化且此后不更改时。
对于类,当您没有将您的类设计为子类(IMO)时。
对于方法,当您没有设计子类重写方法的代码时。
对于局部变量,您希望访问匿名内部类中的变量。(当然,您也可以将它们用于其他局部变量—我不倾向于这样做,但我知道有些人会这样做。当然,对于方法之外的代码来说,这种差异是不可见的。
你说得太模糊了,最终意味着很多事情:http://en.wikipedia.org/wiki/Final_(Java)
另外,请参阅相关讨论:https://softwareengineering.stackexchange.com/questions/115690/why-declare-final-variables-inside-methods,其中链接到以下文章:
http://www.javapractices.com/topic/TopicAction.do?Id=23自由地使用最后一个关键字来传达你的意图。最后一个关键字有多个含义:
- final class不能扩展
- final方法不能被重写
- final字段、参数和局部变量不能更改它们的
在最后一种情况下,可以理解原语的"value"在通常意义上,对象的"值"是指对象的身份,而不是状态。一旦最终对象引用的标识是固定的,它仍然可以改变它的状态,但不能改变它的身份。声明作为final的原语字段自动确保线程安全场。
有些人习惯性地将形参声明为final,因为这几乎总是期望的行为。另一些人则觉得这句话啰嗦,不太真实受益。
一致地对局部变量使用final(适当时)可以也要有用。它将注意力引向非最终的局部变量,这些变量通常有更多与之相关的逻辑例如,结果变量,累加器,循环变量)。许多找到这冗长的。一个合理的方法是使用final代替local变量中至少有一个非final局部变量方法;这有助于快速区分非最终的局部其他变量
使用final:
- 清楚传达你的意图
- 允许编译器和虚拟执行小优化的机器
- 清楚地标记下列项目更简单的行为-最后说,"如果你正在寻找。复杂性,你在这里找不到。"
局部变量只能在final
中使用
final
修饰符可以用来防止setter方法中的滑动。
public void setLimit(int limit) {
/*this.*/limit = limit;
}
显然是错误的;需要加入this.
。在
final
public void setLimit(final int limit) {
limit = limit;
}
会导致编译错误
每个可能是final的变量都应该这样声明吗?
是的。
很多人没有意识到编译器可以做多少来帮助你避免常见的问题:
// Final parameters cannot be reassigned. This sometimes happens accidentally
// and sometimes because people see them as convenient local variables.
publc void myFunction(final int myIntParam) {
// Let's declare a local variable
final String myLocalString;
// ... there's some code here ...
// Here, the compiler knows whether this variable has been assigned
// The programmer knows that it has been assigned only once
return myLocalString.toUpperCase(Locale.ENGLISH);
}