Можете ли вы сохранить переменную внутри предложения if? - PullRequest
15 голосов
/ 19 февраля 2009

Я жду ответа "нет" на этот вопрос.

Мне было интересно, можете ли вы сохранить переменную одновременно с проверкой в ​​предложении if.

Допустим, у меня есть этот код.

if(foo!=null){
  if(foo.getBar()!=null){
    Bar bar = foo.getBar();
    System.out.println("Success: " + bar);
  } else {
    System.out.println("Failure.");
  }
} else {
  System.out.println("Failure.");
}

Я теперь обращаюсь к "неудаче" - независимо друг от друга, даже если результат тот же. Я мог бы собрать их так:

if(foo!=null && foo.getBar()!=null){
  Bar bar = foo.getBar();
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failure.");
} 

Много аккуратного кода уже. если foo равен нулю, он остановится и не будет пытаться использовать foo.getBar (в if), поэтому я не получу NPE. Последнее, что я хотел бы улучшить, и главный вопрос: действительно ли я дал вызов функции foo.getBar () дважды? Было бы неплохо уйти от второго идентичного вызова, если getBar () будет очень тяжелой операцией. Поэтому мне интересно, есть ли возможность сделать что-то похожее на это:

if(foo!=null && (Bar bar = foo.getBar())!=null){
  Bar bar = foo.getBar();
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failure.");
}

Мне бы пришлось разбить его на два разных if, если я бы хотел сделать

Bar bar = foo.getBar();
if (bar!=null) ...

Ответы [ 6 ]

31 голосов
/ 19 февраля 2009

Это самое близкое, что вы можете получить:

Bar bar;
if(foo!=null && (bar = foo.getBar())!=null){
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failiure.");
}
12 голосов
/ 19 февраля 2009

Я использовал эту технику при переборе строк из BufferedReader:

BufferedReader br = // create reader
String line
while ((line = br.readLine()) != null) {
    // process the line
}

Так что да, вы можете выполнить присваивание и результат, который будет левой переменной, которую вы затем сможете проверить. Однако объявлять переменные внутри теста недопустимо, так как они будут ограничены только этим выражением.

7 голосов
/ 19 февраля 2009

, если вы хотите ограничить область бара, я бы добавил {и} к коду, который разместил Майкл.

void foo()
{
    // some code ...

    // this block limits the scope of "Bar bar" so that the rest of the method cannot see 
    // it.
    {
        Bar bar;
        if(foo!=null && (bar = foo.getBar())!=null){
            System.out.println("Success: " + bar);
        } else {
            System.out.println("Failiure.");
        }
    }
}

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

2 голосов
/ 19 февраля 2009

Из отдела «Мой язык программирования лучше вашего языка программирования»: В Groovy вы можете использовать «?». Оператор:

Bar bar = foo?.bar
if (bar != null) {
}

В Java это хороший шаблон (*):

Bar bar = foo == null ? null : foo.getBar();
if (bar != null) {
}

*: то, что вы можете сохранить в ваших руках.

1 голос
/ 19 февраля 2009

Три пункта, которые полностью не отвечают на вопрос:

null это зло. Не пишите методы, которые его возвращают. Ваша проблема с примером исчезнет.

Я думаю, вы можете пропустить инкапсуляцию. Вместо foo.getBar() можно ли сделать интерфейс foo таким, чтобы вы выполняли операцию "не говори"?

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

0 голосов
/ 22 марта 2018

На самом деле я думаю, что это способ сделать это с помощью Java Optional, вот пример:

Optional.ofNullable("text").ifPresent( $0 -> {
  System.out.println($0.toUpperCase());
});

Или в вашем случае:

  if(foo != null){
      Optional.ofNullable(foo.getBar()).ifPresent(bar -> {
          System.out.println("Success: " + bar);
      });
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...