NullPointerException и лучший способ с ним справиться - PullRequest
4 голосов
/ 12 мая 2010

Примечание: это домашнее задание / задание не отвечайте, если не хотите.

Хорошо, после некоторого поиска и прочтения:

Как проверить, является ли элемент массива нулевым, чтобы избежать исключения NullPointerException в Java Изящно избегая исключения NullPointerException в Java http://c2.com/cgi/wiki?NullPointerException

Я до сих пор не добился прогресса в устранении ошибки NullPointerException в моем коде, фрагмент для сомнительного кода:

int findElement(String element) {
          int retval = 0;

            for ( int i = 0; i < setElements.length; i++) {
               if ( setElements[i].equals(element) ) {  // This line 31  here
                  return retval = i;

               }
               else {
                   return retval = -1;
               }
           }

          return retval;
       }

       void add(String newValue) {
            int elem = findElement(newValue);
            if( numberOfElements < maxNumberOfElements && elem != -1 ) {
               setElements[numberOfElements] = newValue;
               numberOfElements++;
            } else { System.out.println("Element " + newValue + "already exist"); }
       }

Компилируется, но добавление нового элемента в набор приводит к ошибке NullPointerException.

D:\javaprojects>java SetDemo
Enter string element to be added
A
You entered A
Exception in thread "main" java.lang.NullPointerException
        at Set.findElement(Set.java:31)
        at Set.add(Set.java:44)
        at SetDemo.main(Set.java:145)

Я добавил еще одну проверку, хотя, честно говоря, понятия не имею, имеет ли это право на строку 31. if (setElements! = null && setElements [i] .equals (element)), но все равно не радует.

Документация / советы или объяснения приветствуются.

обучение, люпин

Ответы [ 7 ]

4 голосов
/ 12 мая 2010

Вы инициализировали setElements где-нибудь? Значение:

String[] setElements = new String[100];

Если вы просто объявляете переменную массива:

String[] setElements;

как член данных вашего класса инициализируется как null. Вы должны указать на что-то. Вы можете сделать это встроенным:

public class MyClass {
  private String[] setElements = new String[100];
  ...
}

или в конструкторе:

public class MyClass {
  private String[] setElements;

  public MyClass() {
    setElements = new String[100];
  }
  ...
}
3 голосов
/ 12 мая 2010

Опубликовать весь класс - этот фрагмент бесполезен.

Вы делаете две серьезные ошибки: не верите компилятору и считаете, что ваш код верен.

Если JVM скажет вам, что проблема в строке 31, поверьте.

Я предполагаю, что setElements[i] равно нулю.

3 голосов
/ 12 мая 2010

Цикл for в findElement не имеет смысла.

for ( int i = 0; i < setElements.length; i++) {
               if ( setElements[i].equals(element) ) {  // This line 31  here
                  return retval = i;

               }
               else {
                   return retval = -1;
               }
           }

Вы должны пройти через все значения перед возвратом -1, только тогда вы знаете, что в наборе нет элемента, который соответствует element.

3 голосов
/ 12 мая 2010

Должно быть setElements[i] != null && setElements[i].equals(element). Если коллекция содержит нулевые элементы, вы попытаетесь разыменовать нулевую ссылку при вызове метода equals для этого элемента.

Что касается NullPointerException - вы должны никогда поймать его. Для вещей, которые не должны быть нулевыми, они должны быть правильно инициализированы. Для тех вещей, которые не могут быть нулевыми - они должны быть проверены на нулевые, прежде чем разыменовывать их (то есть вызывать методы для них).

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

1 голос
/ 12 мая 2010

Вы не должны пытаться перехватить исключение нулевого указателя. Вместо этого лучший способ избежать нулевых указателей:

  • В любой функции, которая принимает параметры, где вы предполагаете, что параметр ненулевой, всегда проверяйте, что параметр ненулевой, и генерируйте исключение IllegalArgumentException, если оно нулевое.
  • Всякий раз, когда вы вызываете функцию, которая не допускает нулевые параметры, убедитесь, что вы не передаете нулевой указатель на эту функцию; если вы уже знаете, что объект не равен NULL (поскольку вы уже проверили его и создали исключение IllegalArgumentException), вам не нужно перепроверять; в противном случае вам следует дважды проверить, что объект не равен NULL, прежде чем передавать его.

Поскольку вы не проверяете параметры вашего findElement и не добавляете функции, вполне возможно, что параметры являются виновниками. Добавьте соответствующую проверку и сгенерируйте IllegalArgumentException, если они нулевые. Если после этого вы получите исключение IllegalArgumentException, значит, вы решили свою проблему. Если нет, то вы по крайней мере знаете, что проблема не в параметре, а в другом месте кода.

1 голос
/ 12 мая 2010

Попробуйте проверить сам элемент на ноль, а не массив:

setElements[i] != null && setElements[i].equals(element)
0 голосов
/ 12 мая 2010

Теперь это работает, благодаря Ларсу, Игорю и остальным, кто потратил время на критику кода, есть логическая ошибка, которая не была проверена, в любом случае, вот исправленный рабочий код, наконец, меня беспокоит, я занимаюсь читерством?: (

int findElement(String element) {
          int retval = 0;

            for ( int i = 0; i < setElements.length; i++) { //loop first to the array and only return -1 once we can't find it.         
       //setElements[i] != null is the NullPointerException killer :)


               if ( setElements[i] != null && setElements[i].equals(element) ) {
                  return retval = i;

               } 
            retval = -1; 
           }

          return retval;
       }

       void add(String newValue) {
            int elem = findElement(newValue);
            if( numberOfElements < maxNumberOfElements && elem == -1 ) { # == instead of != as I only need to add if elements is non-existing 
               setElements[numberOfElements] = newValue;
               numberOfElements++;
            } 
       }

с благодарностью, Люпин

...