2013-05-12 86 views
0

我正在阅读Bruce Eckel第4版中的Thinking in Java。在章初始化&清理,页:189在第二对第一点提到:由于静态初始化而被调用的构造函数

即使它没有明确使用static关键字构造函数实际上是一个静态方法。

我有下面的代码:

class Bar { 
    Bar() { 
     System.out.println("Bar Creation"); 
    } 
} 

class Foo { 
    static int x = 10; 
    static Bar b = new Bar(); 

    Foo() { 
     System.out.println("Foo Creation"); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     System.out.println(Foo.x); 
    } 
} 

如果它说的是真的Foo的构造函数应该被调用。我没有看到下面这段代码发生。

输出是:

Bar Creation 
10 

有人能澄清这是什么意思?

我尽力引用这本书。我不认为在该陈述之前或之后的部分与该陈述在该问题的背景下有很多相关性。

感谢,

Gudge

+0

感谢您的所有意见。我完全理解,除非创建对象,否则构造函数将不会被调用。那么这本书中的陈述意味着什么。 – gudge 2013-05-12 14:39:03

回答

4

Foo()没有理由因为您提到课程而被调用。静态初始化程序static Bar b = new Bar();在加载类时调用;静态方法由您的代码调用。

我猜什么书的意思是,构造像在静态方法调度是静态的:那就是,没有办法继承并重写一个构造函数,调用位置的构造,或者一个静态方法,总是指编译时确定的某个特定的类。

(构造函数这staticness是“工厂”的对象,其在它们的实例方法构造对象。动机)

+0

感谢您的解释。 – gudge 2013-05-12 14:45:48

3

很简单,因为你还没有创建的Foo新实例来访问它

静态字段x如果你创造了new Foo()构造函数的代码会接到电话。由于x是静态成员字段,因此其不需要以创建持有人类的实例以访问该字段。

访问x的另一种方式是新的Foo().x,但不需要创建新对象。

“条形码创建”打印的原因是,因为Foo声明的静态字段被分配为。有关初始化规范,请参见JLS 12.4.1

1

构造函数在创建新对象后调用。我不会把它的静态方法,因为它必须有一个实例,该实例是通过默认访问this

public class Main { 
    public Main() { 
     // static methods do not have a `this` 
     System.out.println("Main called" + this.getClass()); 
    } 

    public static void main(String... ignore) { 
     new Main(); 
    } 
} 

如果反编译的字节代码,你可以看到static方法

$ javap -c -p -cp . Main 
Compiled from "Main.java" 
public class Main { 
    public Main(); 
    Code: 
     0: aload_0  
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: getstatic  #2     // Field java/lang/System.out:Ljava/io/PrintStream; 
     7: new   #3     // class java/lang/StringBuilder 
     10: dup   
     11: invokespecial #4     // Method java/lang/StringBuilder."<init>":()V 
     14: ldc   #5     // String Main called 
     16: invokevirtual #6     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
     19: aload_0  
     20: invokevirtual #7     // Method java/lang/Object.getClass:()Ljava/lang/Class; 
     23: invokevirtual #8     // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 
     26: invokevirtual #9     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
     29: invokevirtual #10     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     32: return   

    public static void main(java.lang.String...); 
    Code: 
     0: new   #11     // class Main 
     3: dup   
     4: invokespecial #12     // Method "<init>":()V 
     7: pop   
     8: return   
} 

注:static方法有不同的修饰符。

1

除非您在Foo类上调用new(),否则不会调用构造函数。由于新的关键字在内部调用构造函数。您只需使用其名称访问类的静态字段即可,因为您无需创建实例。

0

你是新newing了富,而不是你newing酒吧作为一个静态字段富。您可以访问某个类中的静态变量,而无需构建它的一个实例。

0

只有在使用new关键字时才会调用构造函数。既然你没有做new Foo(),那么构造函数就不会被调用。

相关问题