Предварительно созданный массив Java - PullRequest
0 голосов
/ 04 октября 2019

Попытка предварительно создать экземпляр массива JTextFields в простом графическом интерфейсе, который я делаю. Я помещаю их в массив, чтобы при смене состояний я мог просматривать их циклически и очищать данные с помощью простого цикла for. Программа падает после того, как я создал каждый объект, использованный в окне в конструкторе. Я включил 2 строки, где я объявляю массив и объекты с 5 кнопками. Я в том числе и то, как я создаю экземпляр каждого из TextFields. Код вызывал сбой при вызове моего метода clear, исключений нулевого указателя. при ближайшем рассмотрении я вижу, что все мои поля [0] через fields [4] равны нулю. Я не знаю почему. tf1 - tf5 не равны нулю

//instantiation of fields t1, t2, t3, t4, t5 and fields array
private JTextField tf1, tf2, tf3, tf4, tf5;
private JTextField[] fields  = {tf1, tf2, tf3, tf4, tf5};

//In the constructor
tf1 = new JTextField();

//clear method called after all objects are instantiated
private void clear() { for(JTextField f : fields) f.setText(""); }

ожидаемые поля [0] будут иметь то же значение tf1, но равны нулю;

Ответы [ 5 ]

3 голосов
/ 04 октября 2019

Соблюдайте следующий код:

public class Main
{
  public static void main(String[] args)
  {
    Main m = null;
    var ms = new Main[]{m};
    m = new Main();
    System.out.println(m);
    System.out.println(ms[0]);
  }
}

Вывод:

Main@5acf9800
null

Массивы не сохраняют ссылку на переменную при их создании. Вместо этого они копируют значение ссылки в тот момент времени. Даже если значение ссылки изменится, значение в массиве останется прежним.

Если вы не собираетесь менять свой массив (вообще), вы можете сделать что-то вроде следующего:

//instantiation of fields t1, t2, t3, t4, t5 and fields array
private JTextField tf1, tf2, tf3, tf4, tf5;
private JTextField[] fields;

//In the constructor
tf1 = new JTextField();
//instantiate the others as well if you'd like
fields = new JTextField[] {tf1, tf2, tf3, tf4, tf5};

//clear method called after all objects are instantiated
private void clear() { for(JTextField f : fields) f.setText(""); }
...
// anytime you update tf1 later, update fields[0].
// anytime you update tf2 later, update fields[1].
//     ...            ...            ...

Обычно было бы лучше просто сохранить переменные или просто сохранить массив / коллекцию. Управление одним набором переменных уже достаточно раздражает;зачем создавать себе сложнее, создав два сета?

0 голосов
/ 05 октября 2019

использовать unmodifiableList вместо массива

Ваши текстовые поля tf1, tf2, tf3, tf4, tf5, вероятно, не изменятся?

private List<JTextField> fields = Collections.unmodifiableList( Arrays.asList(
    tf1,
    tf2,
    tf3,
    tf4,
    tf5 ) );

тогда функция clear() равна

private void clear() { fields.forEach( f -> f.setText( "" ) ); };
0 голосов
/ 04 октября 2019

Когда вы устанавливаете значение для tf1, вы должны повторно добавить в список. Если вы этого не сделаете, только переменная tf1 будет иметь значение, а не элемент Array. Как исправить, например:

tf1 = (некоторое значение) ; fields[0] = tf1;

0 голосов
/ 04 октября 2019

Ваши JTextField ссылки tf1, tf2, tf3, tf4 и tf5 не инициализируются во время инициализации массива.

Таким образом, учитывая, что Java равен pass-by-value, ваш массив инициализируется значениями null.

Когда вы присваиваете tf1 значение, ему назначается новая ссылка на объект,таким образом, это не влияет на предыдущий объект, на который он указывал (если есть).

0 голосов
/ 04 октября 2019

Если вы хотите создать массив из пяти JTextField объектов, вы можете просто сделать следующее ...

JTextField[] fields = new JTextField[5];
for (int i = 0; i < 5; i++) {
    fields[i] = new JTextField();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...