繁体   English   中英

有一个实例变量作为最终的点?

[英]point of having an instance variable as final?

将实例变量作为最终变量有什么意义?

那么将该变量设置为静态最终变量不是更好吗?

因为如果它不能被任何对象更改,那么它与类(静态)变量相同,对吗?

不。 static意味着它在类的所有实例中都是相同的。 final意味着它在初始分配后不可分配。 因此,对于非静态最终变量,两个实例可能具有不同的值。

您可能希望将变量设为 final 的原因有很多; 最好的之一是清晰度。 如果我阅读了一个方法并注意到 foo 是最终的,我不必担心它在下面的位置发生变化 - 因为它不是; 它不能。 我可以对带有 final 变量的代码进行更多更改而不必担心(“我在 bar 之前或之后更改了 foo 的值,这有关系吗?”),因为我知道某些变量不会更改。 它还侧重于那些可能发生变化的变量我的注意-他们是值得更多的关注的人。

两个原因:

1) 从类设计的角度来看,它允许程序员依赖于字段自实例化后不会改变的事实——所谓的“ 不可变对象”(应用于类成员,而不是对象的引用)。 Java教程说:

不可变对象在并发应用程序中特别有用。 因为它们不能改变状态,所以它们不会被线程干扰破坏或在不一致的状态下被观察到。

不可变对象是各种编程风格的基石,例如纯函数式编程。

2)第二个原因是JVM优化。 如果所有字段都是最终的,那么 JVM 知道对象的状态不能改变,因此它可以进行许多优化,例如省略线程安全检查等。

我猜您正在考虑简单的情况,例如:

 private final int num = 3;

可以更好地写成:

 private static final int NUM = 3;

但是,通常您会引用可变的对象,因此不能在类之间共享:

 private final List<Node> children = new ArrayList<Children>();

或者,一个传入或派生在构造函数中的值:

 public final class MyThing {
      private final String name;
      public MyThing(String name) {
          this.name = name;
      }
      [...]
 }

注意: final字段可以在构造函数(或实例初始化器)中分配,而不仅仅是作为声明的一部分。

您可以为其分配一个特定于对象实例的值,而使用静态类变量则无法做到这一点。

它可以防止其他程序员从做愚蠢的事情,他们不应该想试试做...

class A{
    public final int x;

    A(int arg){
        x = arg;  // This is legal  !!!
    }
}

public class HelloWorld{

     public static void main(String []args){
         A  a = new A(1);
         A  b = new A(2);
         System.out.printf("a.x = %d, b.x = %d", a.x, b.x);
     }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM