首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >“很少有程序员意识到类的构造函数和方法可以在其初始化之前运行”

“很少有程序员意识到类的构造函数和方法可以在其初始化之前运行”
EN

Stack Overflow用户
提问于 2011-11-18 02:05:44
回答 3查看 435关注 0票数 18

在官方的Java指南“Programming with assertions”中指出(页面的最后一段)

很少有程序员意识到类的构造函数和方法可以在其初始化之前运行。当这种情况发生时,类的不变量很可能还没有建立,这可能会导致严重而微妙的错误。

这是什么意思?什么时候会发生这种情况?这是我在日常使用Java时必须关心的事情吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-18 02:10:04

基本上,他们谈到了以下情况:

代码语言:javascript
复制
public class Foo {
    public static Foo INSTANCE = new Foo(); // Prints null

    public static String s = "bar";

    public Foo() {
        System.out.println(s);
    }
}

正如你所看到的,在这种情况下,构造器在静态字段s的初始化器之前运行,即在类的完全初始化之前。这只是一个简单的例子,但当涉及到多个类时,它可能会变得更复杂。

这在你的日常工作中并不常见,但你需要意识到这种可能性,并在编写代码时避免它。

票数 29
EN

Stack Overflow用户

发布于 2011-11-18 02:10:50

例如,考虑构造函数中的虚方法分派。

代码语言:javascript
复制
class Foo {
   Foo() {
      int a = bar();        
      b = 7;
   }

   private int b;

   protected int baz() { assert b == 7; return b; } ;

   protected abstract int bar();
}

如果一个子类碰巧从它们的bar实现中调用了baz,他们就会命中断言。该对象尚未完成构造,因此Foo基类处于某种状态。

票数 5
EN

Stack Overflow用户

发布于 2011-11-18 02:11:08

我认为它们指的是逻辑初始化。例如,您的类A具有在使用任何业务方法之前必须调用的方法init()。但是其他使用这个类的程序员还没有读过手册,也没有写过new A().foo()。在这种情况下,foo()可能无法正常工作。在这种情况下,断言可能是有用的。您可以在开始时检查init()未被调用并抛出断言。

构造函数也是如此。当有人扩展你的类A时,可能会发生这种情况:

代码语言:javascript
复制
class B extends A {
    B() {
        foo(); // init() must be called before foo!
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8172074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档