Изящно избегая NullPointerException в Java - PullRequest
22 голосов
/ 08 июня 2009

Рассмотрим эту строку:

if (object.getAttribute("someAttr").equals("true")) { // ....

Очевидно, что эта строка является потенциальной ошибкой, атрибут может быть null, и мы получим NullPointerException. Таким образом, нам нужно изменить его на один из двух вариантов:

Первый вариант:

if ("true".equals(object.getAttribute("someAttr"))) { // ....

Второй вариант:

String attr = object.getAttribute("someAttr");
if (attr != null) {
    if (attr.equals("true")) { // ....

Первый вариант неудобен для чтения, но более лаконичен, а второй ясен в намерениях, но многословен.

Какой вариант вы предпочитаете с точки зрения читабельности?

Ответы [ 9 ]

27 голосов
/ 08 июня 2009

Я всегда использовал

if ("true".equals(object.getAttribute("someAttr"))) { // ....

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

17 голосов
/ 08 июня 2009

Во втором варианте вы можете воспользоваться коротким замыканием &&:

String attr = object.getAttribute("someAttr");
if (attr != null && attr.equals("true")) { // ....
2 голосов
/ 08 июня 2009

В некоторых ситуациях краткий подход кажется неправильным, но фактически становится идиоматическим. Это один из них; другой что-то вроде:

String line;
while ((line = bufferedReader.readLine()) != null) {
  // Use line
}

Побочные эффекты в состоянии? Немыслимо! За исключением того, что это в основном лучше, чем альтернативы, когда вы узнаете конкретную модель.

Этот шаблон похож - он настолько распространен в Java, что я ожидаю, что любой опытный разработчик узнает его. Результат приятно лаконичен. (Забавно, но иногда я вижу код C #, который использует ту же идиому без необходимости - оператор равенства прекрасно работает со строками в C #.)

Итог: используйте первую версию и ознакомьтесь с ней.

1 голос
/ 08 июня 2009

Всегда стремитесь к более короткому коду, учитывая, что оба они функционально эквивалентны. Особенно в таком случае, когда читаемость не принесена в жертву.

1 голос
/ 08 июня 2009

Мне нравится вариант 1, и я бы сказал, что он достаточно читабелен.

Вариант 3, кстати, должен был бы ввести метод getAttribute, который принимает значение по умолчанию в качестве параметра.

0 голосов
/ 29 апреля 2016

Вот мой подход, хотя класс PropertyUtil нужен, но он записывается только один раз:

/**
 * Generic method to encapsulate type casting and preventing nullPointers.
 * 
 * @param <T>          The Type expected from the result value.
 * @param o            The object to cast.
 * @param typedDefault The default value, should be of Type T.
 * 
 * @return Type casted o, of default.
 */
public static <T> T getOrDefault (Object o, T typedDefault) {
    if (null == o) {
        return typedDefault;
    }
    return (T) o;
}

Код клиента может сделать это:

PropertyUtil.getOrDefault(obj.getAttribute("someAttr"), "").equals("true");

или, для списка:

PropertyUtil.getOrDefault(
    genericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST
).contains(element);

Или потребителю List, который бы отклонил Object:

consumeOnlyList(
    PropertyUtil.getOrDefault(
        enericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST
    )
)

По умолчанию может использоваться шаблон нулевого объекта https://en.wikipedia.org/wiki/Null_Object_pattern

0 голосов
/ 05 марта 2015

У меня есть другой ответ;

List<Map<String, Object>> group = jjDatabase.separateRow(db.Select("SELECT * FROM access_user_group  WHERE user_id=1 ;"));

В моей базе данных нет «group_c80» как столбца в «access_user_group», поэтому в get (0) .get («group_c80») исключения исключений нулевого указателя. Но я обработал это с помощью кода ниже:

for (int j = 1; j < 100; j++) {
                    String rulId="0";//defult value,to privent null pointer exeption in group_c
                    try {
                        rulId = group.get(0).get("group_c" + j)).toString();
                    } catch (Exception ex) {
                        ServerLog.Print( "Handeled error in database for " + "group_c" + (j < 10 ? "0" + j : j) +"This error handeled and mot efect in program");
                        rulId = "0";
                    }}
0 голосов
/ 08 июня 2009

Это очень хороший вопрос. Я обычно использую не изящные:

if (object.getAttribute("someAttr") != null && object.getAttribute("someAttr").equals("true")) { // ....

(и я больше не буду его использовать)

0 голосов
/ 08 июня 2009

Util.isEmpty(string) - возвращает string == null || string.trim().isEmpty() Util.notNull(string) возвращает "", если string == null, иначе строка. Util.isNotEmpty(string) возвращается! Util.isEmpty(string)

И у нас есть соглашение, что для строк Util.isEmpty(string) семантически означает истину, а Util.isNotEmpty(string) семантически означает ложь.

...