-2

私はこのコンストラクターを持っています:

public class SentinelT<T> extends NodeT<T> {

    //constructs an empty Sentinel linked to no other Nodes
    public SentinelT() {
        super(null, null, null);
    this.prev = this;
    this.next = this;
    }
...
}

したがって、this.prevまたはthis.nextの値を変更しようとしたり、これらの値にブール演算子を使用しようとしたりすると、NullPointerExceptionが発生します。例えば:

public boolean isEmpty() {
    return this.prev == this && this.next == this;
}

NullPointerExceptionをスローします。スーパーコンストラクターやnull値について何も理解していないような気がします...助けてくれてありがとう。

*編集:NodeTコンストラクターを追加し、例外をスローするインスタンス化を追加します

//NodeT class for a doubly linked list of T
public class NodeT<T> {
    T data;
    NodeT<T> prev;
    NodeT<T> next;

    //constructs a Node object
    public NodeT(T data, NodeT<T> prev, NodeT<T> next) {
    this.data = data;
    this.prev = prev;
    this.next = next;
    }

* edit2:異なるクラス、stringHeaderがSentinelTで行われるクラスのフィールドであると想定しますstringHeader = new SentinelT();

    public void testIsEmpty(Tester t) {
    initData();

    t.checkExpect(stringHeader.isEmpty(), true);
}
4

4 に答える 4

2

Well, this can't be null ever. Therefore, either prev or next must be null. Your constructor assigns this to both prev and next, so that can't be the reason one of them is null. Therefore, there must be other code you're not showing that sets one (or both) of them to null.

EDIT

On second thought, just because a value is null, doesn't mean it'll throw NPE here.

SECOND EDIT

With testIsEmpty code being revealed, then either t or stringHeader must be null.

于 2013-03-09T00:34:44.327 に答える
1

もっと多くのコードを見ずに何が間違っているのかをはっきりと言うのは難しいですが、null 以外の値をチェックするときに「NullPointerException」が発生しているとあなたは言います。デバッガーを使用して isEmpty にブレークポイントを設定し、isEmpty の実行中に this.prev と this.next が null でないことを証明しましたか? ブレークポイントを使用して、これらのデータ メンバーの値に関する仮定を検証することを強くお勧めします。

EDIT - あなたの編集を見たとき: これは、エラーが発生している場所よりも多くのコードを表示する必要がある理由の代表的な例です。多くの場合、話には続きがあります。デバッガーはコーダーの親友です。デバッガーで仮定を確認します。

于 2013-03-09T00:34:21.790 に答える
0

これについて明確にしましょう:

public boolean isEmpty() {
    return this.prev == this && this.next == this;
}

そのメソッドは をスローできませんNullPointerException。それが実行する操作はどれも、例外をスローできません。

  • thisnullそうすることはできず、NPEthis.prevthis.nextスローすることはできません
  • を使用して参照を(またはその他の参照)==と比較すると、NPE をスローできません。null

したがって、NPE を取得している場合、それは別の場所からのものであり、スタック トレースを誤解しています。


2 番目の例:

t.checkExpect(stringHeader.isEmpty(), true);

この例では、NPEをスローする方法がいくつかあります。

  • その場合、 NPEstringHeaderがスローされます。nullstringHeader.isEmpty()
  • の場合、呼び出しによって NPE がスローされtます。nullt.checkExpect

checkExpect(理論的には)または呼び出し内で NPE がスローされる可能性もありますisEmptyが、スタックトレースはそれが発生した証拠を提供します。


これから学ぶべき教訓:

  • スタック トレースを注意深く読み、正しく解釈する方法を学びます。
  • 書いたコードを読んでください。注意深く読んでください。
  • Java コンストラクトが NPE をスローできるものと、NPE またはその他の組み込み例外をスローできないものを理解していることを確認してください。(場合によっては、いくつかの微妙な点があります...ただし、ここではありません。)
  • 証拠によって裏付けられていない結論に飛びつかないでください。「あなたはそうすることに多くの時間を浪費する可能性が高いので...あなたの「結論」が間違っていることが判明した場合.
  • 理解できない場合は、さらに証拠を探してください。
    • デバッガーを使用して、ブレークポイントの設定、変数の調査、コードのシングル ステップなどを行います。
    • ロギングまたは (一時的な) トレース プリントを追加します。
    • 頭の中で、または紙の上で「手で実行」します。
  • 他の人に助けを求める場合は、関連するすべてのコード スタック トレースとその他の証拠を確認して、自分で判断できるようにする必要があります。証拠の(おそらく間違った)解釈を提供するだけでは、有用な助けは得られません.
  • 問題が他の誰かのコードにあると思い込まないでください。「もしかしたら、私の教授が私たちに使用させたこのテスター パッケージの問題ではないでしょうか?」.... 違う!
于 2013-03-09T01:53:43.310 に答える
0

私がこれが起こっていることを確認できる唯一の方法は、ifstringHeaderまたはtis null...

(jlordo の小道具t)...

于 2013-03-09T00:43:24.180 に答える