Почему объект невидим? - PullRequest
       33

Почему объект невидим?

0 голосов
/ 30 ноября 2010

У меня есть класс. В этом классе я объявляю приватную переменную private Agent agent;. В моем классе у меня есть

private Thread controller = new Thread() {
...
}

В приведенном выше private thread я вызываю getParameter, который является частным методом рассматриваемого класса. В пределах getParameter я называю один из методов agent. В результате я получаю NullPointerException. Итак, я заключаю, что agent не видно из getParameter.

Почему это? Может быть, причина этого в том, что getParameter находится внутри private Thread? И, если это так, как можно решить описанную проблему?

ДОБАВЛЕНО

Я понял, что мне нужно быть более конкретным. Мой код организован так:

public class GameWindow {
   ...
   private Agent agent;
   ...
   private Thread controller = new Thread() {
        public void run() {
           ...
           Agent agent = new Agent();
           ...
           parameter = getParameter();
        }
  }
  ...
  private String getParameter() {   
     ...
     agent.someMethod();
     ...
  }
}

ДОБАВЛЕНО 2 В GameWindow у меня есть:

public void startWindow() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            controller.start();
        }
    });
}

Ответы [ 4 ]

8 голосов
/ 30 ноября 2010

NullPointerException не имеет ничего общего с видимостью.Вы, вероятно, вызываете метод getParameter для нулевого объекта.Ваша переменная agent объявлена, но не инициализирована.Вы можете закодировать что-то вроде:

private Agent agent;
private Thread controller = new Thread() {
    agent = new Agent();
    // ...
    agent.getParameter(); // should not throw a NullPointerException
}

ОБНОВЛЕНИЕ ПОСЛЕ КОДА БЫЛО ДОБАВЛЕНО

Ваш код имеет два определения agent.Первый в классе:

private Agent agent;

А второй внутри вашего run() метода:

Agent agent = new Agent();

Ваш getParameter() метод не знает agent, определенный внутриметод run().Он знает только член agent класса, который не был инициализирован.Ваша проблема будет решена, если вы удалите второе определение agent:

public void run() {
       ...
       // Agent agent = new Agent();
       agent = new Agent(); // works fine: you are initiliazing the class member
       ...
       parameter = getParameter();
 }

OLD UPDATE : NullPointerException выбрасывается в методе getParameter().Поэтому я понимаю, что ваш код выглядит следующим образом:

private Something getParameter() {
    agent.someMethod(); // exception thrown here
}

Если это ваш код, проблема остается той же: agent не инициализирован.Вы должны инициализировать его перед вызовом любого из его методов внутри метода getParameter().

3 голосов
/ 30 ноября 2010

Агент никогда не был инициализирован.Вы хотите что-то вроде этого:
Agent agent = new Agent();

2 голосов
/ 30 ноября 2010

Вы, кажется, создаете этот новый поток в инициализаторе экземпляра.Это означает, что содержащийся экземпляр может быть не полностью инициализирован при запуске потока (вы не показываете, где вы вызываете start()).


И некоторые незапрошенные советы: (1) donне делайте поток подкласса, создайте Runnable и (2) не создавайте свои собственные потоки, используйте ExecutorService

1 голос
/ 30 ноября 2010

Так же Роман, но позвольте мне добавить одно уточняющее замечание.

Если у вас нет видимости для объекта, вы получите сообщение об ошибке при попытке компиляции. Исключение с нулевым указателем - это ошибка RUNTIME, а не ошибка времени компиляции. Вы никогда и никогда не получите исключение нулевого указателя для проблемы видимости по той простой причине, что вы не сможете запустить программу, если у вас есть проблемы с видимостью, потому что компиляция не удалась.

Исключение нулевого указателя означает, что вы не присвоили фактический экземпляр объекта переменной. Это может означать, что вы вообще никогда не создавали экземпляр, или это может означать, что одно объявление скрывает другое, как здесь.

...