在Java中,有一种做法是声明每个变量(本地或类),如果它们确实是参数,则声明final。
尽管这使代码更加冗长,但是这有助于简化代码的读取/抓取,并且由于意图被明确标记,因此还可以防止错误。
您对此有何想法,您会怎么做?
在Java中,有一种做法是声明每个变量(本地或类),如果它们确实是参数,则声明final。
尽管这使代码更加冗长,但是这有助于简化代码的读取/抓取,并且由于意图被明确标记,因此还可以防止错误。
您对此有何想法,您会怎么做?
Answers:
我认为这都与良好的编码风格有关。当然,您可以编写出色而健壮的程序,而无需使用大量final
任何地方修饰符,但是当您考虑一下时...
添加final
到所有不应改变的内容加进去,只会缩小您(或下一个正在处理代码的程序员)误解或滥用导致代码生成的思维过程的可能性。至少当他们现在想要更改您以前不可变的内容时,它应该会发出一些响声。
刚开始时,final
在代码中看到很多关键字看起来有点尴尬,但是很快您就会停止注意到单词本身,而只会想到,这一点永远都不会改变继续(您可以从我这里获取它;-)
我认为这是个好习惯。我并不是一直在使用它,但是只要有条件,就可以标记出final
要执行的操作。
final
,如果您犯了错误,编译器显然不会让您继续。
final
可以在您保存时随时添加(不变的变量)。
final
。98%的时间没有影响,%1的时间给您带来的不便是小小的麻烦,但是1%的时间使我免于做一些愚蠢或意外的事情是值得的。
final
当我“清理...”我的代码时,我总是让Eclipse在各处添加修饰符。到处都意味着即使在catch()块中,并且如前所述,过一会儿您将不会注意到它们。当然,如果我要创建一种语言,则final
它将是默认语言,而a var
或modifiable
将是可选关键字。
痴迷于:
考虑但要谨慎使用:
除非感到肛门,否则忽略:
该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);
}
一些链接:
关于声明每个可能的变量,我非常教条final
。其中包括方法参数,局部变量,很少包括值对象字段。我到处声明最终变量的三个主要原因:
但是,我确实认为,最终类和方法几乎没有最终变量引用有用。final
与这些声明一起使用时,关键字只是提供了自动测试的障碍,并以您从未料过的方式使用了代码。
final
变量和方法参数对性能没有影响,因为它未在字节码中表示。
有效的Java的标题为“支持不可变对象”。将字段声明为final可以帮助您朝此方向迈出一些小步,但是,真正不可变的对象当然不止于此。
如果您知道对象是不可变的,则可以在许多线程/客户端之间共享它们以供读取,而无需担心同步,并且更容易推断程序的运行方式。
我从来没有遇到过在变量上使用final关键字阻止我犯错的情况,所以目前我认为这是浪费时间。
除非有真正的理由这样做(例如,您想就该变量为最终变量提出具体观点),否则我不愿意这样做,因为我发现它会使代码的可读性降低。
但是,如果找不到它,则使代码更难阅读或编写更长的时间,那么请务必使用它。
编辑:作为一种澄清(并试图赢回不赞成票),我并不是说不要将常量标记为final,而是要不要做类似的事情:
public String doSomething() {
final String first = someReallyComplicatedExpressionToGetTheString();
final String second = anotherReallyComplicatedExpressionToGetAnother();
return first+second;
}
(我认为)这只会使代码更难阅读。
还值得记住的是,所有 final操作都是防止您重新分配变量,它不会使它不变或类似的东西。
final
(以及通常不可变的对象)对错误的数量和影响具有重大影响。
听起来,反对使用final关键字的最大争论之一是“这是不必要的”,并且“浪费了空间”。
如果我们承认此处许多出色的文章所指出的“ final”的许多好处,同时承认它需要更多的键入和空间,那么我认为Java应该默认将变量设为“ final”,并要求将事物标记为“可变”。
final
除了“写得太久”,“使代码变得笨拙”之外,没有任何反对的论点。有几个论点final
。如果您不想手动输入,我们可以在保存时自动添加。
我final
一直都在使用对象属性。
final
当在对象属性上使用时,关键字具有可见性语义。基本上,设置最终对象属性的值是在构造函数返回之前进行的。这意味着只要您不让this
引用转义构造函数,并且将其final
用于所有您的属性,你的目标是(在Java 5的语义)保证的广告进行适当构造,并且因为它是不可变的也可以放心地发布到其他线程。
不可变的对象不仅与线程安全有关。它们还使您可以更轻松地推断程序中的状态转换,因为可以更改的空间是有意为之的,并且如果始终使用,则完全限于仅应更改的内容。
有时我还会使方法定型,但不那么频繁。我很少把课程定下来。我通常这样做是因为我几乎不需要。我通常不太多使用继承。我更喜欢使用接口和对象组合-这也使它适合于我发现通常更易于测试的设计。当您编写接口而不是具体类的代码时,则不需要在测试时使用继承,就象使用jMock这样的框架一样,使用接口创建模拟对象比使用具体类要容易得多。
我想我应该把大部分课程都定下来,但是我还没有习惯。
显然,final应该用于常量并强制不变性,但是方法还有另一个重要用途。
有效的Java对此有一个整体(第15项),指出了意外继承的陷阱。实际上,如果您没有为继承设计和编写类,则从该类继承会带来意想不到的问题(该项目提供了一个很好的例子)。因此,建议您在不希望从其继承的任何类和/或方法上使用final。
这可能看起来很苛刻,但这是有道理的。如果要编写供其他人使用的类库,那么您不希望它们从非为它设计的东西中继承-您将自己锁定在该类的特定实现中以实现向后兼容。如果您在团队中进行编码,则没有什么可以阻止团队中的另一个成员(如果确实需要)删除决赛。但是关键字使他们思考自己在做什么,并警告他们继承的类不是为此而设计的,因此应格外小心。
final
为每种方法中的每个参数选择类型都会给编码人员和代码读取人员造成很大的困扰。
一旦刺激超出合理范围,请切换到Scala,默认情况下参数为final。
或者,您始终可以使用代码样式工具来自动为您执行此操作。所有IDE都将它们实现或作为插件来实现。
Final与Java中的变量一起使用时,可以替代C ++中的常量。因此,当final和static用于变量时,它变得不可变。同时使迁移的C ++程序员很高兴;-)
与引用变量一起使用时,尽管可以操纵该对象,但它不允许您重新引用该对象。
当final与方法一起使用时,它不允许子类重写该方法。
一旦用法非常明确,应谨慎使用。它主要取决于设计,因为在该方法上使用final不利于多态。
当您确定该变量的值将/永远不会更改时,应仅将其用于变量。还要确保遵循SUN鼓励的编码约定。例如:final int COLOR_RED = 1; (大写字母由下划线分隔)
对于引用变量,仅当我们需要对特定对象的不变引用时才使用它。
关于可读性部分,请确保在使用final修饰符时注释起着非常重要的作用。
对于论点,我认为不需要它们。Mostley他们只是在伤害阅读能力。重新分配一个自变量非常愚蠢,以至于我应该非常确信它们无论如何都可以当作常量来对待。
Eclipse将最终的颜色涂成红色的事实使我更容易发现代码中的变量声明,我认为这在大多数情况下都提高了可读性。
我试图强制执行所有变量都应为最终变量的规则,这是没有极端理由的。回答“这个变量是什么?”要容易得多。问题,您是否只需要找到初始化并有信心就可以了。
实际上,现在几天来,我对非最终变量感到非常紧张。这就像是把刀悬挂在头顶的线中,还是只是把它放在厨房的抽屉里一样。
最终变量只是获取值的一种好方法。
非最终变量绑定到某些易错算法的一部分。
一个不错的功能是,在大多数情况下,当选择在算法中不使用变量时,解决方法是改写一种方法,这通常可以显着改善代码。
我已经编码了一段时间,并在可能的情况下使用final。经过一段时间(对于变量,方法参数和类属性),我可以说我的变量中有90%(或更多)实际上是最终变量。我认为在您不想修改变量时的好处(我以前见过,有时很痛苦)会为代码中的额外键入和额外的“最终”关键字带来好处。
话虽这么说,如果我要设计一种语言,除非每个其他关键字都没有修改,否则我将使每个变量都成为最终变量。
我认为,对于类和方法,我很少使用final。这是一个或多或少复杂的设计选择,除非您的类是一个实用程序类(在这种情况下,您应该只有一个私有构造函数)。
在需要时,我还使用Collections.unmodifiable ...创建无法修改的列表。
对事件侦听器使用匿名本地类,这是Java中的一种常见模式。final关键字最常见的用法是确保范围内的变量可供偶数侦听器访问。
但是,如果您发现自己需要在代码中放入很多最终语句。这可能是您做错了一个很好的提示。
上面发布的文章提供了以下示例:
public void doSomething(int i, int j) {
final int n = i + j; // must be declared final
Comparator comp = new Comparator() {
public int compare(Object left, Object right) {
return n; // return copy of a local variable
}
};
}
强烈建议将final 用于常量。但是,我不会将它用于方法或类(或至少要考虑一会儿),因为它会使测试更加困难,甚至不是不可能。如果绝对必须使类或方法最终定型,请确保该类实现某些接口,以便您可以模拟实现相同的接口。