0

Bruce Eckel 4th Edition の Thinking in Java を読んでいます。Chapter Initialization & Cleanup, page : 189 の 2 番目の段落の最初の箇条書きで次のように述べています。

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

誰かがそれが何を意味するのかを明確にすることができますか?

頑張って本を引用してみました。そのステートメントの前またはその後の部分は、質問の文脈でこのステートメントとあまり関連していないと思います。

ありがとう、

ガッジ

4

6 に答える 6

3

Foo静的フィールドにアクセスするための新しいインスタンスを作成していないという理由だけx

new Foo()コンストラクター コードを作成した場合は、呼び出されます。x は静的メンバー フィールドであるため、そのフィールドにアクセスするためにホルダー クラスのインスタンスを作成する必要はありません。

x にアクセスする別の方法は newFoo().xですが、新しい Object の作成は不要です。

そして、「バーの作成」が印刷された理由は、によって宣言された静的フィールドFooが割り当てられているためです。初期化仕様については、JLS 12.4.1を参照してください。

于 2013-05-12T14:18:22.013 に答える
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メソッドには別の修飾子があります。

于 2013-05-12T14:20:07.377 に答える
1

Foo クラスで new() を呼び出さない限り、コンストラクターは呼び出されません。as new キーワードはコンストラクターを内部的に呼び出します。インスタンスを作成する必要がないため、その名前を使用してクラスの静的フィールドにアクセスするだけです。

于 2013-05-12T14:20:13.657 に答える
0

newコンストラクターは、キーワードを使用した場合にのみ呼び出されます。をしないのでnew Foo()、コンストラクターは呼び出されません。

于 2013-05-12T14:31:41.383 に答える
0

Foo を新規作成するのではなく、Foo の静的フィールドとして Bar を新規作成します。クラスのインスタンスを作成しなくても、クラス内の静的変数にアクセスできます。

于 2013-05-12T14:27:02.307 に答える