6

次のようなコンストラクタがあります。

public Agent(){

    this.name = "John";
    this.id = 9;
    this.setTopWorldAgent(this, "Top_World_Agent", true);

}

メソッド呼び出しでヌル ポインター例外が発生しています。setTopWorldAgent メソッドの引数として「this」を使用しているためと思われます。このメソッド呼び出しを削除すると、すべてが正常に表示されます。なぜこれが起こるのですか?他の誰かがこれを経験しましたか?

4

11 に答える 11

8

これをメソッドに渡すことはできますが、setTopWorldAgent() は抽象化できません。コンストラクターで仮想呼び出しを行うことはできません。

オブジェクトのコンストラクターでは、そのオブジェクトまたは基本クラスで定義されたメソッドを呼び出すことができますが、派生クラスの一部がまだ構築されていないため、派生クラスによって提供される何かを呼び出すことは期待できません。setTopWorldAgent() が抽象型の場合、何らかのコンパイラ エラーが発生することが予想されます。

Java では、コンストラクターと派生クラスを使用して驚くべき動作を得ることができます。例を次に示します。

http://en.wikipedia.org/wiki/Virtual_functions#Java_3

C# または C++ に慣れている場合は、仮想関数を呼び出しても安全であり、オーバーライドされた関数を呼び出さないと考えるかもしれません。Java では、派生クラスが完全に構築されていなくても、仮想呼び出しが行われます。

これが起こっていない場合は、setTopWorldAgent() が必要とするすべての部分が初期化されていると考えられます。そうでない場合は、初期化する必要があるのはおそらく this のメンバーの 1 つです。

編集:これはC#だと思った

于 2008-09-24T13:45:45.513 に答える
5

好奇心から、なぜ「this」を同じクラスのメンバー関数に渡すのですか? setTopWorldAgent() は「this」を直接使用できます。コンストラクターまたは setTopWorldAgent() が静的であるようには見えないため、既にアクセスできるメンバー関数を渡す理由がわかりません。

私が何かを見逃していない限り...

于 2008-09-24T13:51:11.727 に答える
2

なぜ引数としてsetTopWorldAgent必要なのですか?this呼び出しによるとインスタンスメソッドなのでthis、パラメータとして受け取らなくても参照できます。

于 2008-09-24T13:49:32.930 に答える
1

要するに、なぜ「これ」を「これ」のメソッドにパラメーターとして渡すのですか?

以下は、あなたが言っていることがあなたに起こっていることをテストするものであり、私はそれに問題はありません.

public class Test {
  public Test() {
    this.hi(this);
  }
  public void hi(Test t) {
    System.out.println(t);
  }

  public static void main(String[] args) throws Exception {
    Test t = new Test();
  }
}
于 2008-09-24T13:49:52.430 に答える
1

setTopWorldAgent がインスタンス メソッドのように見えるのに、なぜこれを渡すのですか?

于 2008-09-24T13:50:06.487 に答える
0

エージェントが ITopWorldAgent を実装している場合は、実際にこれを行う必要があります。


Agent agent = new Agent("John", 9);
agent.setTopWorldAgent(agent, "Top_World_Agent", true);

そうでない場合、なぜあなたは自分のやり方で何かを設定しているのですか?

setTopWorldAgent メソッドの何かが、コンストラクターでまだ初期化されていない値を使用していると思います。

于 2008-09-24T13:52:01.753 に答える
0

thisnull ではないことは確かです。割り当て済みです。

つまり、メソッドに渡す必要はありませんthis。すべてのインスタンス メソッドで自動的に使用できます。メソッドが静的な場合は、インスタンス メソッドにリファクタリングすることができます。

于 2008-09-24T13:45:41.427 に答える
0

"this" は null であってはなりません。そのために例外がスローされていると確信していますか?

メソッドが仮想メソッドである場合、または仮想メソッドを呼び出す場合、サブクラスの変数が初期化される前に、サブクラスに属するメソッドが実行される可能性があることに注意してください。

于 2008-09-24T13:46:30.847 に答える
0

上記のコードは確実に機能するため、エラーは別の場所にある必要があります。null 参照は別の場所にある必要があります。

于 2008-09-24T13:46:53.280 に答える
0

Java の規則では、オブジェクトが完全に構築されていないという単純な理由から、コンストラクターから別のメソッドに 'this' を渡してはいけません。参照しているオブジェクトが矛盾した状態にある可能性があります。実際の 'this' 参照が null であることには驚きましたが、setTopWorldAgent に渡されたときに 'this' の一部のメンバーが null であること、およびこれが原因でメソッドが例外をスローしていることにはまったく驚きません。

通常、別のオブジェクトで「this」への参照を設定する場合など、実際にメンバーにアクセスしたりメソッドを呼び出したりしない限り、コンストラクターから「this」を渡すことで回避できます。

この場合、メソッドはすでに「this」への参照を持っているため、もちろん引数は不要です。

于 2008-09-24T17:24:18.140 に答える
0

答えになってよかったです。「this」をパラメーターとして渡すと、予期しない同時実行の問題が発生する可能性があることを付け加えておきます。基本的に、オブジェクトの状態がスレッドセーフでない可能性のあるコードによって安全に操作されない可能性を提供しています。

于 2008-09-25T03:17:20.540 に答える