2014-02-16 3 views
1

Я использую приведенный ниже код, чтобы проверить, установлена ​​ли инициализированная логическая переменная равным True или False. Когда я пытаюсь запустить этот код, я получаю ошибку NullPointerException.NullPointerException, например, логическая переменная

Может кто-нибудь объяснить, в чем проблема?

public class Scratch { 
    Boolean[] bool = new Boolean[5]; 
    String s = new String(); 


    public static void main(String[] args) { 
     new Scratch().mymethod(); 

    } 

    public void mymethod() { 
     if (s == "Tom"){ 
     System.out.println("Tom"); 
    } 
    System.out.println("S value = "+ s);  

     if (bool[1] == true) { 
      System.out.println("True"); 
     } else { 
      System.out.println("false"); 
     } 
    } 

} 
+0

@Teo: Спасибо за ваши ответы, а также .. – user1050619

ответ

9

Вы создаете массив булевых, не булево, и вы пытаетесь использовать его перед заполнением его с булевыми объектами, так что это не должно быть сюрпризом, что это будет бросить NPE.

Решения:

  • Создать массив булевых и если инициализирован, он будет заполнен по умолчанию ложных значений.
  • Создайте массив логических, если вы должны (например, если используете в JTable-модели), но убедитесь, что каждый элемент инициализирован действительным экземпляром Boolean перед использованием массива.

например, изменение от

Boolean[] bool = new Boolean[5]; 

к

boolean[] bool = new boolean[5]; 

или

Boolean[] bool = {Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, 
     Boolean.FALSE, Boolean.FALSE}; 

Edit

Пожалуйста, поймите, что boolean является примитивным типом, и если логическая переменная явно не инициализирована, ей не присваивается значение, по умолчанию она равна false.

Boolean, с другой стороны, является ссылочным типом, который «блокирует» логическое значение, предоставляет ссылочную переменную, которая может использоваться вместо булевского примитива, где требуются ссылки, например, в коллекциях. Булева переменная, как и для всех ссылочных типов, по умолчанию имеет значение null, если явно не назначено экземпляру.


Edit 2

Обратите внимание, что если вы используете строки, вы столкнетесь с той же проблемой. Например

String unAssigned; 

if (unAssigned.equals("foo") { 
    System.out.println("the method above throws a NPE"); 
} 

или

String[] strings = new String[5]; 
// all the strings items above are null 

Edit 3

Вы задаетесь вопросом, почему это не сделать то же самое: String s = new String();

  • Вы создание новый объект String и присвоение его переменной s, поэтому s не является нулевым.
  • С булевым массивом да, вы назначаете новый массив переменной, поэтому массив не является нулевым, но элементы, хранящиеся в массиве, равны нулю.
  • Вы не используете массив строк в любом месте, так что это не где-то рядом с тем же. Давай, давайте сравним яблоки с яблоками, а не яблоками с апельсинами.
  • Как в стороне, вы почти никогда не должны использовать new String(), поскольку он обходит пул строк и может привести к неэффективному коду с ненужным созданием дополнительных объектов String.
+1

Возможно, кое-что добавить о примитивов против штучной примитивов, они могут быть довольно запутанным для начинающих. – Zavior

+0

Я смущен, что я пытаюсь использовать его перед его заполнением. Не получилось ли оно инициализироваться нулями автоматически? – user1050619

+0

@ user1050619: да, это инициализирует значение null, и это ваша проблема. См. Править для ответа. –

2

Эта "проблема" из-за бокса о примитив Java ..

Boolean отличается, что boolean, как Integer и int, например ...

Boolean является объект (класс оболочки), поэтому он имеет значение true, false, но имеет значение NULL. Хотя boolean является примитивной переменного, поэтому она имеет только «реальное» значение логического: правда и ложь

Линка разъясняется в руководстве: Логический класс оборачивает значение примитивного логического типа в объект. Объект типа Boolean содержит одно поле, тип которого является логическим.

Boolean b Так, имеет 3 значения: true, false и null.

boolean b, имеет 2 значения: true и false

Значения null могут быть присвоены любым переменным, кроме переменных примитивных типов. И логическая переменная «инициализирована» до нулевого значения, потому что вы еще не вызываете конструктор Boolean class ...

Итак, если вы это сделаете: String s = "HELLO", вы можете использовать его, потому что с помощью этой части кода вы автоматически вызываете конструктор String. Но если вы это сделаете: String s; его значение - null. Дело samt в класс Boolean wrapper.

Для уточнения вы можете прочитать: Creating Objects

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