Java 构造函数中的对象逃逸总是一个问题吗?

发布于 2024-11-18 01:09:58 字数 370 浏览 2 评论 0原文

出于线程安全的原因,有争议:

不要让 this 引用在构造过程中逃逸。

但这始终是一个问题,应该通过使用 newInstance() 方法来避免吗?在我的模型类中,我有一个 TableModel ,它应该在模型类中实例化,但它也需要对模型类的引用:

public class MainModel {

   TableModel tableMode;

   public MainModel() {
      tableModel = new MyTableModel(this);
   }
}

如果构造函数不立即使用它,那么它是安全的还是应该以任何方式避免它?

For thread-safety reasons it is argumented:

Do not allow the this reference to escape during construction.

But is this always an issue and should be avoided by using newInstance() methods? Inside my model class I have a TableModel which should be instantiated, within the model class, but which also requires a reference to the model class:

public class MainModel {

   TableModel tableMode;

   public MainModel() {
      tableModel = new MyTableModel(this);
   }
}

If the constructor does not use this right away is it then safe or should it be avoided in any means?

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

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

发布评论

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

评论(3

默嘫て 2024-11-25 01:09:58

如果 MyTableModel 中的任何内容都不会在其他线程等中执行任何操作 - 或者将变量复制到其他共享数据(例如静态变量) - 那么它是安全的。

当然,如果 MyTableModel 开始在其构造函数内调用 MainModel 引用上的方法,那么它将在尚未完全初始化的对象上调用它们,这可以导致问题 - 但这与线程无关。

写了更多博客不久前就谈到过这一点。

If nothing in the MyTableModel is going to do anything in other threads etc - or copy the variable to some other shared data, such as a static variable - then it's safe.

Of course, if MyTableModel starts calling methods on the MainModel reference within its constructor, then it'll be calling them on a not-completely-initialized-yet object, which can cause issues - but that's not really threading related.

I blogged a bit more on this a while ago.

提笔书几行 2024-11-25 01:09:58

不,我不认为这总是一个问题。在我看来,一个好的类的设计使得构造函数限制它对其依赖项所做的活动,将其行为仅限于初始化。如果是这种情况,那么 this 仅仅因为将其泄漏给另一个构造函数就泄漏到另一个线程,那将是非常令人惊讶的。

唯一一次根本不允许您泄漏对 this 的引用是在调用超级构造函数之前。换句话说,您无法将参数传递给依赖于 this 的超级构造函数,无论是由于您调用实例方法还是使用 this 构造某些内容。

我认为更好的问题可能是为什么 MyTableModel 需要查看 MainModel 的实例?通常,双向可见性是某些有害耦合的标志。

No, I don't think it's always a problem. In my opinion a good class is designed such that the constructor limits the activity it does on its dependents, limiting its behaviour only to initialization. If that's the case it would be very surprising for this to leak to another thread simply because you leaked it to another constructor.

The only time you are not permitted at all to leak a reference to this is before the super contructor has been called. In other words, you can't pass an argument to the super constructor that has a dependency on this, be it due to you calling an instance method or constructing something using this.

I think a better question might be why does MyTableModel need to see an instance of MainModel? Often bi-directional visibility is a sign of some harmful coupling.

旧人哭 2024-11-25 01:09:58

最佳实践不是纠正错误,而是最不可能引入错误、令人困惑或难以维护的模式。我见过一些非常困难的代码,但运行得很好。

例如,我记得一个名为 c 的类,它完全写在一行中以节省空间(没有换行符),并且仅使用单字符变量/字段,并且具有一到两个字符方法。这并不是故意混淆的,开发者认为这是最有效的。只要你不需要理解它或改变它,这个类就可以很好地工作。

Best pratice is not about correcting bugs, but patterns which are least likely to introduce bugs, be confusing or difficult to maintain. I have seen some increadibly difficult code which works just fine.

e.g. I remember one class called c which was written entirely on one line to save space (no line breaks) and only used single character variables/fields and had one to two character methods. This wasn't deliberately obfuscated, the developer thought this was the most efficient. The class worked fine as long as you didn't need to understand it of change it.

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