2015-01-29 3 views
0

что бы вы сказать, является лучшей практикой при реализации следующей задачи:избежать «Потенциальный доступа указателя нулевого»

MyClass myVariable = null; 
if (..condition 1..) { 
    myVariable = new MyClass(1); 
} else if (..condition 2..) { 
    myVariable = new MyClass(2); 
} 

myVariable.execute(); 

Каких бы хорошим решением для предупреждения?

  1. отделочного else

    final MyClass myVariable; 
    .... 
    } else { 
        // let's say this assert makes sense here 
        Assert.fail("This should not happen"); 
    } 
    
  2. бросок RuntimeException

    final MyClass myVariable; 
    .... 
    } else { 
        throw new RuntimeException("Some message, like <should not happen>"); 
    } 
    
  3. Проверка на NPE

    final MyClass myVariable; 
    .... 
    if (myVariable != null) { 
        myVariable.execute(); 
    } 
    
  4. Другое идеи?

Заранее благодарен!

ответ

1

Это зависит от того, должно ли быть всегда условие 1 или условие 2. Если условие 2 является полностью противоположным условию 1, вы можете заменить else if (..condition 2..) на else и решить вашу проблему.

Если это не так, и факт, что оба условия 1 и условие 2 являются ложными, указывает на некорректный ввод, я бы выбрал исключение.

Если сценарий, в котором оба условия являются ложными, является допустимым сценарием, я должен проверить, что myVariable не имеет значения null перед вызовом myVariable.execute().

0

Лучше следующее.

final param; 
if (..condition 1..) { 
    param = 1; 
} else if (..condition 2..) { 
    param = 2; 
} else { 
    throw new IllegalArgumentException("no condition matches"); 
} 

new MyClass(param).execute(); 

Если ваши условия просты, попробуйте переписать цепочку if-else с помощью футляра-переключателя. Лучше.

+0

Вы должны только бросать 'IllegalArgumentException', если есть вызываемый метод * незаконного * аргумента *. В контексте нет указаний на то, что 'condition 1' и' condition 2' являются аргументами проверки. –

+0

@StephenC, я согласен с вашим заявлением. Однако я абсолютно уверен, что «условие» OP зависит от аргумента, который можно упомянуть в исключении. Если это неверно, 'IllegalStateException' звучит лучше. Точка в моем решении состоит в том, что (1) исключение throw является чем-то неправильным и (2) минимизирует дублирование кода: есть только один вызов конструктора. – AlexR

+0

Вы (по сути) рекомендуете, чтобы ОП выбрасывал конкретное исключение, когда он уже предлагает бросить «RuntimeException» или «AssertionError». Это только хорошая рекомендация, если конкретное рекомендуемое исключение * больше * подходит, чем тот, который он/она уже рассматривает. –

0

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

0

Если вы всегда можете инициализировать переменную, использовать if-else, который заканчивается else:

MyClass myClass; 

if (...) 
    myClass = new MyClass(1); 
else if (...) 
    myClass = new MyClass(2); 
else if (...) 
    ... 
else 
    myClass = new MyClass(n); 

myClass.execute(); 

Если вы не можете всегда инициализирует переменную, и вы хотите использовать только переменную, когда инициализирован:

MyClass myClass; 

if (...) 
    myClass = new MyClass(1); 
else if (...) 
    myClass = new MyClass(2); 
else if (...) 
    ... 

if (myClass != null) 
    myClass.execute(); 

Если вы не можете всегда инициализирует переменную, но это необходимо:

MyClass myClass; 

if (...) 
    myClass = new MyClass(1); 
else if (...) 
    myClass = new MyClass(2); 
else if (...) 
    ... 
else 
    throw new Exception(...);// or notify the user and exit 

myClass.execute(); 

Другой подход заключается в определении init() метод:

MyClass myClass = init(...); 

// check if myClass is != null if init can return a null 
myClass.execute(); 

MyClass init(...) { 
    if (...) 
     return new MyClass(1); 
    else if (...) 
     return new MyClass(2); 
    else if (...) 
     ... 
    else 
     return new MyClass(n);// or return null 

Короче говоря, это зависит от случая вы.

0

что бы вы сказать, является лучшей практикой при реализации следующей задачи

Это зависит от контекста:

  • Это зависит от (глубокой) с целью проверки condition 1 и condition 2.

  • Это зависит от того, что это значит для них, чтобы быть оба ложными:

    • Является ли это «нормальное» состояние?

    • Это ошибка ввода пользователем?

    • Это ошибка программирования в коде, который вызвал этот метод?

    • Это ошибка программирования в этом коде; например нарушение инварианта?

    • Что-то еще?

  • Это зависит от того, как вы хотите, чтобы этот случай обрабатывался.

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


... что бы вы сказали, это лучшая практика ...

Я бы не использовать фразу «лучшая практика» для чего-то вроде этого. Даже если бы я знал контекст. Всякий раз, когда я слышу фразу «лучшая практика» в вопросе, у меня создается впечатление, что кто-то хочет «решение для куки-печенья», которое они могут применить, не задумываясь.

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

И ... «любое решение, предупреждающее предупреждение» - это не правильный подход.

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