Тернарный оператор Java, плохо оценивающий нуль - PullRequest
1 голос
/ 27 марта 2019

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

public class Toy {

    private String name;

    public Toy(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

И у меня было исключение, которое работало аналогично этому (например, просто отображал данные обо всех объектах, на которых мыработали до того как все пошло плохо);Я также включил основной для теста:

public class ToyFactoryException extends Exception {

    public ToyFactoryException(Toy firstToy, Toy secondToy) {
            super("An error occurred when manufacturing: " + 
                       "\nfirstToy: " + firstToy != null ? firstToy.getName() : null + 
                       "\nsecondToy: " + secondToy != null ? secondToy.getName() : null);
        }

    public static void main(String[] args) {
        try {

            throw new ToyFactoryException(null, new Toy("hi"));

        } catch (ToyFactoryException myException) {

            System.out.println("It should be there.");

        } catch (Exception exception) {

            System.out.println("But it's there instead.");

        }
    }

}

Как я писал в первом блоке catch, исключение должно быть перехвачено в исключении ToyFactoryException.

Однако, в исключении, он пытается прочитать firstToy.getName () прямо здесь: firstToy != null ? firstToy.getName() : null

firstToy != null должен иметь значение false, что означает, что он не должен пытатьсяпозвоните firstToy.getName() в первую очередь.Когда вы пишете в обратном порядке:

public ToyFactoryException(Toy firstToy, Toy secondToy) {
    super("An error occurred when manufacturing: " + 
               "\nfirstToy: " + firstToy != null ? null : firstToy.getName() + 
               "\nsecondToy: " + secondToy != null ? secondToy.getName() : null);
        }

Вы понимаете, что вместо этого теперь читается null, что означает, что он действительно читает firstToy != null как истину.

Если вместо этого вы пишете main (null - второй параметр конструктора):

public static void main(String[] args) {
    try {

        throw new ToyFactoryException(new Toy("hi"), null);

    } catch (ToyFactoryException myException) {

        System.out.println("It should be there.");

    } catch (Exception exception) {

        System.out.println("But it's there instead.");

    }
}

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

Почему троичное условие на firstToy не оценивает null должным образом?

1 Ответ

5 голосов
/ 27 марта 2019

Вы должны поставить круглые скобки вокруг вашего условного выражения.

Это:

"string " + firstToy != null ? firstToy.getName() : null

означает это:

("string " + firstToy) != null ? firstToy.getName() : null

Вам нужно это:

"string " + (firstToy != null ? firstToy.getName() : null) 
...