2015-03-02 3 views
1

У меня есть класс вроде этого.Необязательный тип возвращает нулевое значение

public class SomeClass { 

    private Optional<String> testString; 

    public SomeClass() { 
     populateFields(); 
    } 

    public Optional<String> getTestString() { 
     return testString; 
    } 

    private void populateFields() { 
    if(//something is going false here){ 
     testString = functionThatReturnsOptionalString(); 
    } 
    } 

} 

Теперь instanceOfSomeClass.getTestString() возвращает null. Разве необязательно всегда должно содержать ненулевое значение или пустое? Я пытаюсь или избегаю isNull() и просто использую isEmpty() в своем вызывающем.

Если я положил точку останова в первой строке populateFields() и проверил значение в testString в это время, оно отображает значение как null. Значение по умолчанию для этого поля (перед назначением чего-либо) равно null.

Прошу пролить свет на эту ситуацию; и, возможно, правильное использование опционального?

+1

Вы можете инициализировать 'testString':' private Дополнительно testString = new Необязательно ... ' –

+1

@helpYou - Вернее, используя статический заводский метод:' Optional.absent() ', если вы используете опции Guava или 'Необязательный.путь()' для опций Java 8. – Dogs

+0

Нет специального магии для Необязательного - это класс, как любой другой. Это означает, что значение по умолчанию для дополнительных ссылок (как и все ссылки) равно null. – immibis

ответ

5

Необязательный всегда содержит ненулевое значение или пуст, да, но у вас нет опции, у вас есть ссылка типа Необязательный, указывающий на null. Вам необходимо инициализировать testString, например. до Optional.empty().

Optional не является магии, это объект, как и любой другой, и сама ссылка Optional может быть нулевой. Это содержимое Optional, которое не может быть нулевым.

+0

Ваш ответ имеет смысл для меня, хотя я все еще пропущу полную ясность. «Необязательно, это не волшебство, это объект, как любой другой, а сама необязательная ссылка может быть нулевой. Это содержимое Необязательного, которое не может быть пустым». Можете ли вы привести пример кода? Или укажите мне ресурс. Я имею в виду, так что же такое магия Факультативного? Извините, если это звучит просто. – Gadam

+0

Это не волшебство. Это обычный класс, который может содержать либо ненулевое значение, либо быть пустым. Не уверен, что вам нужно. –

+0

«Это содержимое Необязательного, которое не может быть пустым» - как это выполняется? Что было бы незаконной линией ошибки кода/компилятора? – Gadam

0

Из документации оракулом для дополнительного типа:

Объект-контейнер, который может или не может содержать ненулевое значение.

Итак, да, он вернет null, если для переменной установлено значение null. Дополнительная информация here

0

Из документации Java:

Объект-контейнер, который может содержать или не содержать ненулевое значение. Если присутствует значение , isPresent() вернет true и get() вернет значение .

Хотя конструктор YourClass не создает экземпляр класса Option, поэтому он является нулевым.

public SomeClass() { 
    this.testString = Optional.empty(); 
} 

Источник: http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

+0

'Необязательно' не выставляет конструктор; вы не можете делать 'new Optional'. –

0

Это потому, что ваш первый нужно объекта класса Optional<String> и код имеет только ссылки типа Optional<String>. Объявите (и инициализация) testString следующим образом:

private Optional<String> testString= new Optional<String>() ; 

Или с помощью "бриллиантовый обозначения":

private Optional<String> testString= new Optional<>() ; 

Теперь у вас есть Optional!

1

Мне всегда нравятся внутренние поля класса в качестве их фактических значений и используйте метод return Optional.ofNullable(theField) в методе getter. Это гарантирует, что метод всегда будет возвращать некоторый тип необязательного.Другими словами, вы никогда не сталкиваетесь с ситуацией, когда ваш метод, который должен возвращать необязательный, возвращает null.

Так что в вашем случае:

private String testString; 

... 

public Optional<String> getTestString() { 
     return Optional.ofNullable(testString); 
} 

В дополнительном к «никогда не возвращающейся нулевой» выгоде, этот подход должен быть более себя при использовании вещи, как Gs маршалу экземпляры вашего класса в формат, как JSON , Я не пробовал Gson с вариантами Java 8, но с вариантами Guava они не очень хорошо сериализуются в JSON без адаптера типа. Если вы храните исходное значение и затем обертываете их опциями в своих методах getter, они сериализуются в JSON точно так, как вы ожидали.

+0

Это означает, что я должен преобразовать необязательный , возвращенный функциейThatReturnsOptionalString() в строку сначала. Таким образом, это снова возможно для параметра «Необязательно для строки». Это хорошая идея? – Gadam

+0

Ну, это зависит от профиля использования. Существует дополнительный шаг создания объекта, связанный с моим подходом. В 99,99% применений для такого метода это не имеет значения, но если вы вызываете этот метод 1000 раз в секунду в чрезвычайно чувствительной к производительности ситуации, этот подход может быть слишком дорогостоящим. Если у вас есть ситуация, чувствительная к производительности, определите минимальный порог производительности и измерьте оба подхода, чтобы увидеть, есть ли причина в производительности. ** Но, по всей вероятности, вы не должны быть запрещены производительностью ** – Dogs

+0

Спасибо собакам. Это большая среда данных, где этот код является частью пакетной программы, которая работает и обрабатывает около 6 миллионов записей каждый день (на данный момент). В этом контексте я должен склоняться к просто инициализации testString с помощью опции Optional.empty(); ? – Gadam

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