我有一个如下构造函数:
public Agent(){
this.name = "John";
this.id = 9;
this.setTopWorldAgent(this, "Top_World_Agent", true);
}
我在方法调用中遇到空指针异常。这似乎是因为我在setTopWorldAgent方法中使用'this'作为参数。通过删除此方法调用一切正常。为什么会这样?还有其他人经历过这个吗?
答案 0 :(得分:8)
您可以将此传递给方法,但setTopWorldAgent()不能是抽象的。您无法在构造函数中进行虚拟调用。
在对象的构造函数中,您可以调用在该对象或基类中定义的方法,但是您不能期望调用由派生类提供的内容,因为派生类的某些部分未构造然而。如果setTopWorldAgent()是抽象的,我本来期望某种编译器错误。
在Java中,您可以使用构造函数和派生类获得令人惊讶的行为 - 这是一个示例
http://en.wikipedia.org/wiki/Virtual_functions#Java_3
如果你习惯使用C#或C ++,你可能会认为调用虚函数是安全的,而不是调用被覆盖的函数。在Java中,即使未完全构造派生类,也会进行虚拟调用。
如果这不是正在发生的事情,那么可能是setTopWorldAgent()需要的所有部分都被初始化 - 如果不是,它可能是需要初始化的成员之一。
编辑:认为这是C#
答案 1 :(得分:5)
出于好奇,为什么要将'this'传递给同一个班级的成员函数? setTopWorldAgent()可以直接使用'this'。它看起来不像你的构造函数或setTopWorldAgent()是静态的,所以我不确定为什么你会传递一个它已经有权访问的成员函数。
除非我遗漏了什么......
答案 2 :(得分:2)
为什么setTopWorldAgent
需要this
作为参数?基于调用,它是一个实例方法,因此它可以引用this
而无需将其作为参数接收。
答案 3 :(得分:1)
我认为更重要的是,为什么你要将'this'作为参数传递给'this'中的方法?
以下内容将测试您所发生的事情,并且我没有遇到麻烦。
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();
}
}
答案 4 :(得分:1)
鉴于setTopWorldAgent似乎是一个实例方法,为什么还要将它传递给它呢?
答案 5 :(得分:0)
this
不是空的,这是肯定的。它被分配了。
也就是说,没有必要将this
传递给方法,它在所有实例方法中都自动可用。如果方法是静态的,您可能需要将其重构为实例方法。
答案 6 :(得分:0)
“this”永远不应为null。你确定因为这个而抛出了异常吗?
需要注意的是,如果方法是虚拟的,或者调用任何虚方法,那么属于子类的方法可能会在子类的变量初始化之前运行。
答案 7 :(得分:0)
错误必须在其他地方,因为上面的代码肯定有效,空引用必须是别的。
答案 8 :(得分:0)
如果您的代理正在实施ITopWorldAgent,那么您应该实际执行此操作:
Agent agent = new Agent("John", 9);
agent.setTopWorldAgent(agent, "Top_World_Agent", true);
如果没有,那么为什么你要按照自己的方式设置某些东西?
我假设setTopWorldAgent方法中的某些内容正在使用尚未在构造函数中初始化的值。
答案 9 :(得分:0)
Java的规则规定,您不应该将“this”从其构造函数传递给另一个方法,原因很简单,该对象尚未完全构造。它引用的对象可能处于不一致状态。我很惊讶实际的'this'引用是null,但是当它传递给setTopWorldAgent时,'this'的某个成员为null,并且该方法因为这个而抛出异常,并不感到惊讶。
通常,只要您不实际访问任何成员或调用方法(例如,如果要在另一个对象中设置对“this”的引用),您就可以从构造函数中传递'this'。
在这种情况下,当然这个参数是不必要的,因为该方法已经引用了'this'。
答案 10 :(得分:0)