我有这个构造函数:
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。我有一种感觉,我只是不理解超级构造函数或空值...感谢任何帮助。
*编辑:添加了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);
}
答案 0 :(得分:2)
好吧,this
不能null
。因此,prev
或next
必须为null
。您的构造函数会将this
分配给prev
和next
,因此这不是其中一个null
的原因。因此,必须有其他您未展示的代码,将其中一个(或两个)设置为null
。
修改强>
第二个想法,仅仅因为值为null
,并不意味着它会在这里抛出NPE。
第二次编辑
如果显示testIsEmpty
代码,则t
或stringHeader
必须为null
。
答案 1 :(得分:1)
我很难在没有看到更多代码的情况下确定错误,但是在检查非空值时你说你得到了“NullPointerException”。您是否使用过调试器,并在isEmpty中放置一个断点并证明在执行isEmpty期间this.prev和this.next是非空的?我强烈建议使用断点来验证您对这些数据成员的值的假设。
编辑 - 看到你的编辑:这是一个很好的例子,说明为什么你必须显示的代码多于你提出错误的地方。这个故事往往更多。调试器是编码员最好的朋友。验证调试器中的假设。
答案 2 :(得分:0)
我能看到这种情况的唯一方法是stringHeader
或t
是null
......
(jlordo for t
的道具)...
答案 3 :(得分:0)
让我们明白这一点:
public boolean isEmpty() {
return this.prev == this && this.next == this;
}
该方法不能抛出NullPointerException
。它执行的任何操作都不会抛出任何异常:
this
不能null
因此,this.prev
和this.next
无法抛出NPE ==
将引用与null
(或任何其他引用)进行比较,不能抛出NPE。因此,如果你正在获得一个NPE,那么它来自其他地方......你错误地解释了堆栈跟踪。
第二个例子:
t.checkExpect(stringHeader.isEmpty(), true);
在此示例中,有几种方法可以抛出NPE
。stringHeader
为null
,则stringHeader.isEmpty()
将投放NPE。t
为null
,那么t.checkExpect
电话会抛出一个NPE。理论上也可能在checkExpect
或isEmpty
调用中抛出NPE,但堆栈跟踪会提供已发生的证据。
从中吸取教训: