У меня есть следующее перечисление:
import com.google.common.collect.Maps;
public enum ServiceType {
SOME_SERVICE (4, SomeServiceEntity.class);
private int id;
private Class<? extends ServiceEntity> entityClass;
private static final Map<Integer, ServiceType> LOOKUP = Maps.uniqueIndex(
Arrays.asList(ServiceType.values()),
ServiceType::getId <<=======
);
ServiceType(int id, Class<? extends ServiceEntity> entityClass) {
this.id = id;
this.entityClass = entityClass;
}
public int getId() {
return id;
}
// and other methods....
}
Эта строка кода отмечена Intellij IDEA как:
Method reference invocation 'ServiceType::getId' may produce 'java.lang.NullPointerException'
Как это возможно, когда у меня есть единственный конструктор, который включает в себя мое поле id, а перечисление - это статический список объектов, поэтому все они предполагают наличие идентификатора?
Как я могу избавиться от этого предупреждения?
УПД: Застрял с:
private static final Map<Integer, ServiceType> LOOKUP = Arrays.stream(
ServiceType.values()).collect(Collectors.toMap(
ServiceType::getId, Function.identity()
)
);
@Seelenvirtuose конечно. Но serviceType -> serviceType.getId() все еще предупреждает о NPE, что я не могу найти возможность произойти
Вы повторили одно и то же лямбда-выражение, которое, как я уже объяснил, может вызвать NPE. Если аргумент (в моем примере st) равен null, то выражение st.getId() выдает NPE.
Статический анализ кода не смотрит на фактически назначенные значения, он просто видит небезопасный вызов метода и, таким образом, показывает предупреждение. Он недостаточно умен, чтобы увидеть, что в этом случае он не будет нулевым.
Какая у вас версия Intellij? Я не получаю никаких предупреждений об NPE с этим кодом в 2019.1.3...
@vlumi На самом деле у меня есть старая версия 2018.2.1. Это может быть вещь
@vlumi Я тоже использую 2019.1.3, но он выдает мне предупреждение.




Как говорится в комментарии, вы используете лямбду, которая получает параметр. И когда он равен нулю, это дает NPE.
Поэтому лучше попробуйте что-то вроде:
private static final Map<Integer, ServiceType> LOOKUP =
Arrays
.stream(ServiceType.values())
.Collectors.toMap(ServiceType::getId, Function. identity());
что... э-э... может дать вам такое же предупреждение.
Итак, если вы действительно хотите использовать потоковую передачу здесь, вам, вероятно, придется подавить это предупреждение.
IDEA 2019.3 не будет выдавать предупреждение NPE с образцом, предоставленным GhostCat
ServiceType::getId— это ссылка на метод с эквивалентным лямбда-выражениемst -> st.getId(). В последнем вы видите, что может произойти NPE.