Pergunta

Eu tenho um construtor como o seguinte:

public Agent(){

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

}

Estou recebendo uma exceção de ponteiro nulo aqui na chamada do método. Parece ser porque eu estou usando 'isto' como um argumento no método setTopWorldAgent. Ao remover essa chamada de método Tudo parece bem. Por que isso acontece? Tem mais alguém experimentou este?

Foi útil?

Solução

Você pode passar isso para métodos, mas setTopWorldAgent () não pode ser abstrato. Você não pode fazer uma chamada virtual no construtor.

No construtor de um objeto, você pode chamar métodos definidos no objeto ou base de classes, mas você não pode esperar para chamar algo que será fornecido por uma classe derivada, porque partes da classe derivada não são construídos ainda. Eu teria esperado algum tipo de erro compilador se setTopWorldAgent () era abstrato.

Em Java, você pode obter um comportamento surpreendente com o contructor e classes derivadas - aqui está um exemplo

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

Se você está acostumado a C # ou C ++, você pode pensar que é seguro para chamar funções virtuais e não estar chamando os substituídos. Em Java, a chamada virtual é feita mesmo que a classe derivada não está totalmente construído.

Se isto não é o que está acontecendo, então, presumivelmente, todas as partes deste que setTopWorldAgent () necessidades são inicializados -. Se não, é provavelmente um dos membros desta que precisa ser inicializado

Edit: achava que isso era C #

Outras dicas

Por curiosidade, por que você está passando 'isto' para uma função de membro da mesma classe? setTopWorldAgent () pode usar 'this' diretamente. Ele não se parece com o seu construtor ou setTopWorldAgent () são estáticos, então eu não sei por que você iria passar uma função membro algo que já tem acesso.

A menos que eu estou faltando alguma coisa ...

Por que setTopWorldAgent necessidade this como um argumento? Com base na invocação, é um método de instância, para que ele pudesse fazer referência this sem a necessidade de recebê-lo como um parâmetro.

Eu acho que mais para o ponto, porque na terra você está passando 'isto' como um parâmetro para um método em 'isto'?

O seguinte seria testar o que você diz está acontecendo com você e não tenho problemas com isso.

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();
  }
}

Dado que setTopWorldAgent parece ser um método de instância, por que você está passando por isso para ele de qualquer maneira?

"este" nunca deve ser nulo. Tem a certeza de que a exceção está sendo lançada por causa disso?

Algo para ter cuidado com é que, se o método é virtual, ou chama os métodos virtuais, em seguida, um método que pertence a uma subclasse pode ser executado antes de variáveis ??da subclasse são inicializados.

O erro deve ser em outro lugar porque o código acima definitivamente funciona, a referência nula deve ser outra coisa.

Se o seu agente está a implementar ITopWorldAgent então você deve realmente fazer isso:


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

Se não, então por que você está definindo algo da maneira que você é?

Eu presumo que algo no método setTopWorldAgent está usando um valor que não foi inicializado ainda em seu construtor.

this não é nulo, isso é certeza. Tem sido alocado.

Dito isso, não há necessidade de passar this no método, é automaticamente disponível em todos os métodos de instância. Se o método estático, você pode querer refatorar-lo em um método de instância.

As regras do estado de Java que você nunca deve passar 'isto' para outro método de seu construtor, pela simples razão de que o objeto não foi totalmente construído. Objeto que referências podem estar em um estado inconsistente. Eu estou surpreso que o 'this' referência real é nulo, mas não em todos os surpreso que algum membro de 'this' é nulo quando ele é passado para setTopWorldAgent, e que o método é lançar a exceção por causa disso.

Normalmente, você pode ir longe com o passar do 'isto' de construtores, desde que você realmente não acessar qualquer membros ou métodos de chamada, por exemplo, se você quiser definir uma referência a 'isto' em outro objeto.

Neste caso, claro, o argumento é desnecessário como o método já tem uma referência a 'isto'.

Que bom que você chegou a uma resposta. Eu gostaria de acrescentar que passa 'this' como um parâmetro pode levar a problemas de concorrência inesperados. Você basicamente está fornecendo a possibilidade do estado do objeto a ser insegura manipulados por código de segurança potencialmente não-thread.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top