我有一个如下构造函数:

public Agent(){

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

}

我在方法调用中遇到空指针异常。这似乎是因为我在setTopWorldAgent方法中使用'this'作为参数。通过删除此方法调用一切正常。为什么会这样?还有其他人经历过这个吗?

有帮助吗?

解决方案

您可以将此传递给方法,但setTopWorldAgent()不能是抽象的。您无法在构造函数中进行虚拟调用。

在对象的构造函数中,您可以调用在该对象或基类中定义的方法,但是您不能期望调用由派生类提供的内容,因为派生类的某些部分未构造然而。如果setTopWorldAgent()是抽象的,我本来期望某种编译器错误。

在Java中,您可以使用构造函数和派生类获得令人惊讶的行为 - 这是一个示例

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

如果你习惯使用C#或C ++,你可能会认为调用虚函数是安全的,而不是调用被覆盖的函数。在Java中,即使未完全构造派生类,也会进行虚拟调用。

如果这不是正在发生的事情,那么可能是setTopWorldAgent()需要的所有部分都被初始化 - 如果不是,它可能是需要初始化的成员之一。

编辑:认为这是C#

其他提示

出于好奇,为什么要将'this'传递给同一个班级的成员函数? setTopWorldAgent()可以直接使用'this'。它看起来不像你的构造函数或setTopWorldAgent()是静态的,所以我不确定为什么你会传递一个它已经有权访问的成员函数。

除非我遗漏了什么......

为什么 setTopWorldAgent 需要 this 作为参数?基于调用,它是一个实例方法,因此它可以引用 this 而无需将其作为参数接收。

我认为更重要的是,为什么你要将'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();
  }
}

鉴于setTopWorldAgent似乎是一个实例方法,为什么还要将它传递给它呢?

"这"永远不应该为空。你确定因为这个而抛出了异常吗?

需要注意的是,如果方法是虚拟的,或者调用任何虚方法,那么属于子类的方法可能会在子类的变量初始化之前运行。

错误必须在其他地方,因为上面的代码肯定有效,空引用必须是别的。

如果您的代理正在实施ITopWorldAgent,那么您应该实际执行此操作:


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

如果没有,那你为什么要以你的方式设置某些东西?

我假设setTopWorldAgent方法中的某些内容正在使用尚未在构造函数中初始化的值。

这个不是null,这是肯定的。它被分配了。

也就是说,没有必要将 this 传递给方法,它可以在所有实例方法中自动使用。如果方法是静态的,您可能需要将其重构为实例方法。

Java的规则规定,您不应该将“this”从其构造函数传递给另一个方法,原因很简单,该对象尚未完全构造。它引用的对象可能处于不一致状态。我很惊讶实际的'this'引用是null,但是当它传递给setTopWorldAgent时,'this'的某个成员为null,并且该方法因为这个而抛出异常,并不感到惊讶。

通常,只要您不实际访问任何成员或调用方法(例如,如果要在另一个对象中设置对“this”的引用),您就可以从构造函数中传递'this'。

在这种情况下,当然这个参数是不必要的,因为该方法已经引用了'this'。

很高兴你得到了答案。我想补充说,将'this'作为参数传递会导致意外的并发问题。您基本上提供了可能由非线程安全代码对对象状态进行不安全操作的可能性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top