2013-11-13 4 views
0

У меня есть массив, инициализированный и заполненный, но я не могу получить доступ к его значениям в других методах, чем тот, который он заполняет. Если я пытаюсь работать с ним в других методах, я получаю исключение nullPointerException. Например, если я говорю «System.out.println (board [2] [2])» внутри метода init, он работает, но в другом методе выбрасывается исключение nullPointerException. Я много часов пытался понять, но не знаю, что случилось? Может ли кто-нибудь осветить мою проблему? Это будет высоко ценится. БлагодаряНе удается получить доступ к массиву в методе?

public class Program2 extends JPanel implements ActionListener 
{ 
    private LifeCell[][] board; 
    private JButton next;   
    private JFrame frame; 

    public static void main(String[] args) {new Program2();} 

    public Program2() 
     { 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setContentPane(this); 
      this.init(); 
      frame.pack(); 
      frame.setVisible(true); 
     } 

      public void init() 
      { 
       LifeCell[][] board = new LifeCell[10][10]; 
       this.setPreferredSize(new Dimension(400, 500)); 
       this.setLayout(null); 

       for (int r = 0; r < 10; r++) 
       { 
        for (int c = 0; c < 10; c++) 
        { 
         board[r][c] = new LifeCell(board, r, c); 
         this.add(board[r][c]); 
         board[r][c].setBounds(x,y,40,40); 
         this.setVisible(true); 


         System.out.println(board[2][2]) //works 
        } 
       } 
      } 
     public void test(){ System.out.println(board[2][2])}//doesn't work 
} 
+0

Вопрос уже достаточно отвечен, но я хотел бы добавить, что вы можете настроить IDE так, чтобы он помог вам найти такие проблемы. Например.eclipse поддерживает это: Предпочтения -> Java -> Компилятор Java -> Ошибки/Предупреждения затем включаются. Объявление локальной переменной скрывает другое поле или переменную. – shutefan

ответ

4
LifeCell[][] board = new LifeCell[10][10]; 

должен быть

board = new LifeCell[10][10]; 

Переопределив как LifeCell[][] внутри метода init(), вы создаете новую переменную board которой объем ограничивается этим методом. Затем вы пытаетесь напечатать массив board, который находится в области класса (и неинициализирован), что дает вам ошибки, которые у вас есть.

+0

Большое вам спасибо! Все это время я пробовал разные вещи, и эта небольшая ошибка я сделал. Ты восхитителен! – user2989591

+0

Одна эвристика, которая может помочь вам заметить этот тип ошибок в будущем, заключается в том, чтобы всегда ссылаться на переменные экземпляра (нестатические поля a.k.a.) как 'this.board'. Таким образом, вам не нужно полагаться на подсветку синтаксиса или запоминание, чтобы заметить разницу между экземплярами и локальными переменными. Используйте 'Program2.myField' для ссылки на переменную класса (статическое поле a.k.a.). См. Http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html определения различных типов переменных. – yegeniy

+0

Если у вас есть много локальных переменных в вашем методе, из-за которых вы потеряете следы локалей против экземпляров, вы делаете что-то неправильно. –

1

Это потому, что переменные, объявленные внутри методов, являются переменными local, и они недоступны ни в каком другом методе, кроме как в том случае, если они были объявлены. Чтобы войти в свой второй метод, вам нужно передать его как аргумент метода или просто объявить свой массив как поле класса. Он будет доступен во всех методах такого класса. Как я вижу, вы уже создали такое поле, но вы покрываете его локальной переменной палубой локализации с тем же именем, что и поле.

2

В INIT должно быть:

board = new LifeCell[10][10]; 

С LifeCell[][] board = new LifeCell[10][10]; вы декларирование и Instancing новую локальную переменную с областью действия ограничивается методом инициализации.

2

В java вы можете иметь локальную переменную и переменную экземпляра с тем же именем. Однако порядок приоритета состоит в том, чтобы проверить локальную переменную с именем сначала, а затем переменную экземпляра после, если локальная версия отсутствует (1), если не указано значение this.

Что здесь происходит, вместо инициализации копии экземпляра «платы» вы создаете новую доску, но только локально до init(). Остальная часть вашего класса этого не видит.

board = new LifeCell[10][10]; 

просто удалите декларацию типа слева от платы и она должна знать, чтобы присвоить ее переменной экземпляра. Если быть более точным, можно сказать, this.board = ...

  1. Это звучит так, как будто это удар по производительности, но эти проверки все сделано во время компиляции, и не будет влиять на производительность во время выполнения на всех.
1

LifeCell[][] board = new LifeCell[10][10]; означает, что вы создаете объект типа LifeCell массива и назначение его новый локальную переменную board ОТМЕТЬТЕ, что в данный момент экземпляр переменной board остается пустой. Когда вы выполняете System.out.println(board[2][2]) внутри метода init, используется локальная переменная (поскольку она была объявлена ​​в том же методе). При попытке распечатать значения в методе test() используется таблица переменных экземпляра, которая по-прежнему равна нулю.

Смежные вопросы