设置最终类属性

发布于 2024-10-30 20:15:52 字数 338 浏览 1 评论 0原文

是否可以通过从该对象的构造函数调用的私有方法为最终属性设置值?

public class FinalTest {
  private final Object a;
  //Constructor
  public FinalTest() {
    setA();
  }

  private void setA() {
    a = new Object;
  }
}

对于上面的类,编译器给我一个错误,说我无法从该方法设置“a”的值。

我知道不可能从构造函数外部设置最终变量的值,但在上面的情况下,我实际上是在构造函数内以某种方式执行此操作。那么为什么不允许这样做呢?

Is it possible to set a value for a final attribute from a Private method called from the Constructor of that Object?

public class FinalTest {
  private final Object a;
  //Constructor
  public FinalTest() {
    setA();
  }

  private void setA() {
    a = new Object;
  }
}

For the above class, compiler gives me an error saying I can't set the value for 'a' from the method.

I understand that its not possible to set value for a final variable from outside a constructor, but in the above case, I am actually doing it in a way within the constructor. So why isn't this allowed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倦话 2024-11-06 20:15:52

这是不允许的,因为您可以稍后通过其他一些非构造函数方法调用setA(),这会违反最终保护。由于 Final 是编译时强制执行的操作,因此编译器通过强制在构造函数或内联中​​进行初始化来强制执行 Final。

在您的简单示例中,一切看起来都不错,但如果您后来将类更新为如下所示,问题就会变得更加明显......

public class FinalTest {
  private final Object a;
  //Constructor
  public FinalTest() {
    setA();
  }

  private void setA() {
    a = new Object;
  }

  public void doSomething() {
   this.setA(); // not good because a is final
  }
}

It's not allowed because you could call setA() via some other non-constructor method later on which would violate the final protection. Since final is a compile time enforced operation, the compiler enforces final by forcing initialization to occur in constructors or in-line.

In your simple example, all looks good but if you later updated your class to something like the following, the problem become more obvious...

public class FinalTest {
  private final Object a;
  //Constructor
  public FinalTest() {
    setA();
  }

  private void setA() {
    a = new Object;
  }

  public void doSomething() {
   this.setA(); // not good because a is final
  }
}
最美不过初阳 2024-11-06 20:15:52

请注意:编译器必须假设最坏的情况。通过声明属性“final”,编译器必须确保该属性不能在构造函数之外修改。

例如,在使用反射调用该方法的情况下,编译器永远不会看到它。证明某事可能比证明不可能容易得多,这就是编译器以这种方式工作的原因。

Just a note: The compiler has to assume the worst case scenario. By declaring an attribute "final", the compiler has to ensure that the attribute cannot be modified outside of the constructor.

In a case where the method is called using reflection (for example), the compiler would never see it, ever. It's a lot easier to prove something is possible than impossible, that is why the compiler works the way it does.

缘字诀 2024-11-06 20:15:52

最终检查是在编译时而不是运行时完成的。在您的情况下,编译器无法确定 setA 不会从其他方法调用。

Final checking is done at compile time not at runtime time. In your case compiler can't be sure that setA would not be called from some other method.

断念 2024-11-06 20:15:52

为什么需要从私有方法设置最终变量的值?
您可以这样做:

public class FinalTest {
   private final Object a;
   {
      a=new Object();
   }

   //Constructor
   public FinalTest() {
   }
}

在这种情况下,该对象将在每次 FinalTest 初始化时初始化。

Why do you need to set the value of final variable from a private method ?
You may do it in this way :

public class FinalTest {
   private final Object a;
   {
      a=new Object();
   }

   //Constructor
   public FinalTest() {
   }
}

In this case the object will be initialized on every FinalTest initialization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文