当前位置:  开发笔记 > 编程语言 > 正文

在Java中适用时使用"final"修饰符

如何解决《在Java中适用时使用"final"修饰符》经验,为你挑选了10个好方法。

在Java中,有一种做法是声明每个变量(本地或类),如果确实是参数final.

虽然这使得代码更加冗长,但这有助于轻松阅读/掌握代码,并且还可以防止错误,因为意图已明确标记.

您对此有何看法,您对此有何看法?



1> Alex Miller..:

痴迷于:

最终字段 - 将字段标记为最终强制它们在构造结束时设置,使该字段引用不可变.这样可以安全地发布字段,并且可以避免在以后的读取时进行同步.(请注意,对于对象引用,只有字段引用是不可变的 - 对象引用引用的内容仍然可以更改并影响不变性.)

最终的静态字段 - 虽然我现在使用枚举用于我曾经使用静态最终字段的许多情况.

考虑但明智地使用:

最终类 - 框架/ API设计是我认为的唯一案例.

最终方法 - 与最终类基本相同.如果你正在使用模板方法模式,如疯狂和标记最终的东西,你可能过分依赖继承而不是委托.

忽略除非感觉肛门:

方法参数和局部变量 - 我很可能这样做很大程度上是因为我很懒,我发现它使代码混乱.我将完全承认,我不打算修改的标记参数和局部变量是"更严格".我希望这是默认的.但事实并非如此,而且我发现整个决赛的代码更难以理解.如果我在别人的代码中,我不会把它们拉出去,但是如果我正在编写新的代码,我就不会把它们放进去.一个例外是你需要标记最终的东西以便你可以访问它来自一个匿名的内部类.


关于这个最终主题的多个问题的最佳答案
大多数时候,当我看到前面没有最后一个单词的局部变量并且它无法在那里使用时,它告诉我,我应该在一个新方法中提取一些代码,这个方法返回我将最终生成的期望值.这种情况不适用的情况是当我使用某些流或者需要尝试捕获它时.

2> Johan Pelgri..:

我认为这一切都与良好的编码风格有关.当然,你可以编写好的,健壮的程序而不需要在final任何地方使用很多修饰符,但是当你想到它时......

添加final所有不应改变的东西只会缩小您(或下一个程序员,处理您的代码)会误解或误用导致您的代码的思维过程的可能性.当他们现在想要改变你以前不可改变的东西时,至少应该响起一些钟声.

首先,final在你的代码中看到很多关键字看起来很尴尬,但很快你就会停止注意这个词本身,并且只会想到,这件事情将永远不会改变 - 从这一点 -在(你可以从我这里拿走;-)

我认为这是一个很好的做法.我并不是一直都在使用它,但是当我可以并且标记某些东西时final我会这样做是有意义的.


+1我喜欢`final`.它没有98%的时间有所不同,这是一个小的不便%1的时间,但1%的时间是节省我做一些愚蠢或无意的是值得的.
@Timo这可以工作,但它有缺点,需要在签入后检查,而不是开发人员正在处理代码.对于`final`,如果你犯了错误,编译器显然不会让你继续.
您可以使用静态分析工具(如FindBugs)来代替使​​用参数的final关键字来要求不重新分配参数变量.这样您就可以消除语法负担,并可以通过Continuous Integration工具中的FindBugs检查来强制执行它.
@BertF是的,当我"清理......"我的代码时,我总是让Eclipse在各处添加`final`修饰符.Everywhere意味着即使在catch()块中,如上所述,一段时间后你也不会注意到它们.当然,如果我要创建一种语言,`final`将是默认语言,`var`或`modifiable`将是可选关键字.
每当你保存时,Eclipse都可以选择添加`final`(不变的变量).

3> 小智..:

在使用之前,您确实需要了解final关键字的完整用法.它可以应用于变量,字段,方法和类,并对其有不同的影响

我建议查看下面链接的文章了解更多详情.

关于最终关键字的最后一句话



4> Bruno De Fra..:

final修改,特别是变量,是可以让编译器强制执行约定,一般是明智的手段:确保(本地或实例)变量分配一次(不多不少).通过确保在使用变量之前明确赋值,可以避免常见的情况NullPointerException:

final FileInputStream in;
if(test)
  in = new FileInputStream("foo.txt");
else
  System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned

通过防止变量被多次分配,您可以阻止过于宽泛的范围.而不是这个:

 String msg = null;
 for(int i = 0; i < 10; i++) {
     msg = "We are at position " + i;
     System.out.println(msg);
 }
 msg = null;

我们鼓励您使用此:

 for(int i = 0; i < 10; i++) {
     final String msg = "We are at position " + i;
     System.out.println(msg);
 }

一些链接:

最后的故事("Hardcore Java"一书的免费章节)

一些最终模式

明确的任务



5> Ryan Ransfor..:

我非常教条宣称每个可能的变量final.这包括方法参数,局部变量和很少的值对象字段.我有三个主要原因可以在任何地方声明最终变量:

    声明意图:通过声明一个最终变量,我声明这个变量只能写入一次.这是对其他开发人员的一个微妙暗示,也是编译器的一个重要提示.

    强制执行一次性变量:我相信每个变量在生活中应该只有一个目的.通过给每个变量只有一个目的,可以减少在调试时理解该特定变量的目的所需的时间.

    允许优化:我知道编译器曾经有过性能增强技巧,它特别依赖于变量引用的不变性.我喜欢认为编译器会使用这些旧的性能技巧(或新的).

但是,我确实认为最终的类和方法几乎没有最终变量引用那么有用.final与这些声明一起使用时,关键字只会为自动化测试提供障碍,并以您从未预料到的方式使用您的代码.


`final`变量和方法参数对性能没有影响,因为它没有在字节码中表示.

6> Lars Westerg..:

Effective Java有一个项目"赞成不可变对象".将字段声明为final可以帮助您对此采取一些小步骤,但对于真正不可变的对象,当然还有更多.

如果您知道对象是不可变的,则可以共享它们以便在没有同步担忧的情况下在许多线程/客户端之间进行读取,并且更容易推断出程序的运行方式.


小心 - 最终和不可变是完全不同的概念.它很容易有一个最终的可变对象 - 最终是关于引用,可变性是关于对象实例.final person olaf = new Person(); olaf.setName( "奥拉夫");
但它们密切相关,因为你可以通过将Person.name字段声明为final(并声明类final,并且......)使Person对象成为final.然而,这并不像做"最终人物"那么容易......

7> SCdF..:

我从来没有遇到过变量上的最终关键字阻止我犯错误的情况,所以目前我认为这是浪费时间.

除非有这样做的真正原因(因为你想要对该变量做出最终的具体观点),我宁愿不这样做,因为我发现它使代码的可读性降低.

但是,如果你没有发现它会使代码更难以阅读或更长时间地写入,那么一定要去寻找它.

编辑:作为一个澄清(并尝试赢回选票),我不是说不要将常数标记为最终,我说不要做的事情如下:

public String doSomething() {
  final String first = someReallyComplicatedExpressionToGetTheString();
  final String second = anotherReallyComplicatedExpressionToGetAnother();

  return first+second;
}

它只是使代码(在我看来)更难阅读.

值得记住的是,所有最终的做法都是阻止你重新分配一个变量,它不会让它变成不可变的或类似的东西.


我都是不可变的对象,我从来没有遇到过标记不可变对象final对我有帮助的情况.
我同意我们不应该对局部变量和方法参数使用final,它确实使代码的可读性降低.

8> David Leppik..:

Final应始终用于常量.当定义变量的规则很复杂时,它对于短期变量(在单个方法中)甚至有用.

例如:

final int foo;
if (a)
    foo = 1;
else if (b)
    foo = 2;
else if (c)
    foo = 3;
if (d)        // Compile error:  forgot the 'else'
    foo = 4;
else
    foo = -1;



9> Chris Vest..:

final一直用于对象属性.

final在对象属性上使用时,关键字具有可见性语义.基本上,在构造函数返回之前设置最终对象属性的值.这意味着,只要你不要让this参考逃脱的构造和使用final所有您的属性,你的目标是(在Java 5的语义)保证的广告进行适当构造,并且因为它是不可变的也可以放心地发布到其他线程.

不可变对象不仅仅是线程安全.它们还可以更容易地推断出程序中的状态转换,因为可以改变的空间是有意识的,并且如果一致地使用,则仅限于应该改变的事物.

我有时也会把方法做成最终,但不是经常.我很少把课程定稿.我一般这样做是因为我没有必要这样做.我通常不会使用很多继承.我更喜欢使用接口和对象组合 - 这也适用于我发现通常更容易测试的设计.当您对接口而不是具体类进行编码时,在使用jMock等框架进行测试时,不需要使用继承,使用接口创建模拟对象比使用具体类更容易.

我想我应该让我的大部分班级最终完成,但我还没有进入habbit.



10> RAY..:

听起来,反对使用final关键字的最大争论之一是“这是不必要的”,并且“浪费了空间”。

如果我们承认此处许多出色的文章所指出的“ final”的许多好处,同时承认它需要更多的键入和空间,那么我认为Java应该默认将变量设为“ final”,并要求将事物标记为“可变”。


有成千上万的英语单词可供选择。
推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有