1

次のコードを持つ Parent と Child の 2 つのクラスがあります。

public class Parent {
    public String word;
}

親クラスには public フィールドが 1 つだけ含まれます。

public class Child extends Parent {

//super.word = "Simple field assignment.";
{
    System.out.println(word);
}
String word2 = super.word = "Field assignment.";

{
    System.out.println(word);
    super.word = "Initialization block.";
    System.out.println(word);
}

public Child(){
    super.word="Constructor.";
    System.out.println(word);
}
}

質問したいのは、単純な代入 'super.word = "word"' が許可されない理由ですが、次の二重代入は問題ありません。そして、誰かが後者で正確に何が起こっているかを特定できますか?

また、初期化ブロック内で割り当てが許可されているのはなぜですか?

次のメインプログラムを実行すると:

public class FieldTest {
public static void main (String[] args)
{
    Child c = new Child();
    System.out.println("1: "+c.word);
    System.out.println("2: "+c.word2);
}
}

結果は次のとおりです。

null
Field assignment.
Initialization block.
Constructor.
1: Constructor.
2: Field assignment.
4

5 に答える 5

2

ステートメント

super.word = "Simple field assignment.";

コンストラクター、イニシャライザー、またはメソッドの外側では有効な Java 構文ではありません。宣言時にフィールドを初期化できます

public class Parent {
   public String word = "Don't use mutable public fields!"
}

サブクラスのコンストラクターまたは初期化子でこれらを変更します

public class Child extends Parent {
   public Child() {
      super();
      this.word = "Don't mutate parent state like this...";
   }
}

フィールドと組み合わせた super キーワードは、スーパークラスの変数を非表示にする場合にのみ役立ちます。

public class Child extends Parent {
    public String word = "Only for demonstration purposes - do not hide fields!";

    public Child() {
        super.word = "Mutating the hidden field.";
    }
}

コードからわかるように、これは最終的に本番環境で使用されるものではありませんsuper.someField。キャリアの中で一度も使用した覚えがありません。特定の構文について不明な点がある場合は、CheckStyle と FindBugs を使用してください。具体的な継承の問題を解決するためのヒントが必要な場合は、私に投稿してください。

PS: Java チュートリアルでフィールドを非表示にします

于 2013-06-05T11:05:13.480 に答える
0

コメントアウトされた行を参照している場合

super.word =  "Simple field assignment.";

その行は、クラス本体内で直接「裸」で発生するステートメントであるため、エラーです。その位置では、宣言のみが許可されます。インスタンス初期化子がその例です。

別の点として、 の使用superはまったく不要です。セマンティクスに影響を与えずに削除することも、代わりに使用することもできますがthis、同じ結果になります。

于 2013-06-05T10:44:39.743 に答える
0
    class Check {
    //static block
    static {
        System.out.println("hello from Static");
    }
    //object block

    {
        System.out.println("This is my object block");
    }

    public static void main(String args[]) {
        System.out.println("hello from main");
        Check obj = new check();
    }
}

これは出力です:

hello from Static
hello from main
This is my object block

静的ブロックは、クラスが JVM にロードされるたびに実行されます。一方、オブジェクト ブロックまたはコンストラクタ ブロックは、そのオブジェクトのインスタンスを作成するときに実行されます。

詳細については、次をご覧ください。

http://www.jusfortechies.com/java/core-java/static-blocks.php http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

于 2013-06-05T11:07:05.187 に答える
0

child の定義を次のように変更してみてください

public class Child extends Parent {
{
    super.word = "Simple field assignment.";
    System.out.println(word);
}
String word2 = super.word = "Field assignment.";

{
    System.out.println(word);
    super.word = "Initialization block.";
    System.out.println(word);
}

public Child(){
    super.word="Constructor.";
    System.out.println(word);
}
}

つまり、super.word = "Simple field assignment" をブロック内に配置します。宣言ではないすべてのコードは、初期化ブロック内に配置する必要があります。ここを参照してください。

于 2013-06-05T10:49:10.047 に答える
0

最初の代入はクラス内に直接あるため許可されませんが、他の代入はブロック内にあるため問題ありません。

2 番目の質問に答えるために、何が起こっているか見てみましょう。

  1. Childがインスタンス化されているため、最初のブロックが実行され、word初期化されていない印刷が実行されるため、null.
  2. 属性word2には の値が与えられword、これには の値が与えられ、Field assignment.どちらにもこの文字列が含まれます。
  3. word印刷されます:Field assignment.
  4. word値が与えられますInitialization block.
  5. word印刷されます:Initialization block.
  6. Childのコンストラクターが呼び出されword、値が与えられ、出力Constructor.されます。
  7. の値wordが出力されています:Constructor.
  8. の値word2が出力されています:Field assignment.
于 2013-06-05T10:56:56.447 に答える