Ошибка несоответствия типа в java 8
у меня есть следующий класс со следующим методом.
public class MyClass {
public static <T> T getSomeThing(final int id, final java.lang.reflect.Type type, final Map<Integer, String> someThings) {
final String aThing = someThings.get(id);
if (aThing == null || aThing.isEmpty()) {
return null;
}
return GsonHelper.GSON.fromJson(aThing, type);
}
}
GsonHelper предоставляет мне некоторые com.google.gson.GsonBuilder
public class GsonHelper {
public static final com.google.gson.Gson GSON = getGsonBuilder().create();
public static GsonBuilder getGsonBuilder() {
return new GsonBuilder().setPrettyPrinting()
.enableComplexMapKeySerialization()
.registerTypeAdapter(new com.google.gson.reflect.TypeToken.TypeToken<byte[]>() {
// no body
}.getType(), new Base64TypeAdapter())
.registerTypeHierarchyAdapter(Date.class, new DateTypeAdapter())
.registerTypeHierarchyAdapter(Pattern.class, new PatternTypeAdapter())
.registerTypeAdapterFactory(new ListTypeAdapterFactory())
.registerTypeAdapterFactory(new MapTypeAdapterFactory())
.registerTypeAdapterFactory(new SetTypeAdapterFactory());
}
}
до Java 7 я использовал этот метод, как:
Map<Integer, String> allThings = new HashMap<>();
//FILL allThings with values
if(MyClass.getSomeThing(7, java.lang.Boolean.class, allThings)){
//do something
}
это сработало отлично. потому что метод вернет логическое значение, и я могу использовать это внутри "если". Но когда я перехожу на Java 8, это больше невозможно. Компилятор жалуется на:
несоответствие типов: невозможно преобразовать из объекта boolean
//while this is working but would throw a JsonSyntaxException
final String myString = "myInvalidJsonString";
if(GsonHelper.GSON.fromJson(myString, java.lang.Boolean.class)){
//do something
}
Я знаю, что java.ленг.Boolean может быть null. И я мог бы решить эту проблему с помощью:
final Boolean b = MyClass.getSomeThing(7, java.lang.Boolean.class, allThings);
if(b){
//do something
}
но мне интересно, почему это работает с Java 7, а не в Java 8. (не ответил)
что они изменили? (не ответил)
В чем причина этой ошибки компилятора при переходе с Java 8? (ответил)
2 ответов
метод public static <T> T getSomeThing(final int id, final java.lang.reflect.Type t, final Map<Integer, String> someThings)
не гарантирует возврата Boolean
. Он возвращается T
который определяется вызывающим абонентом и может быть чем угодно, что означает Object
.
The если заявление не могу знать, какого типа T
будет иметь и, следовательно,не может гарантировать его преобразование в логическое.
почему бы не изменить подпись на boolean?
public static boolean getSomeThing(final int id,
final java.lang.reflect.Type t,
final Map<Integer, String> someThings)
или ты в поисках?
public static <T> T getSomeThing(final int id,
final Class<T> clazz,
final Map<Integer, String> someThings)
чем этот код будет компилироваться и работа:
public static void main(String[] args) {
if (getSomeThing(7, Boolean.class, emptyMap())) {
System.out.println("It works!");
}
}
public static <T> T getSomeThing(final int id,
final Class<T> clazz,
final Map<Integer, String> someThings) {
...
}
последняя версия, где результат getSomeThing()
назначена Boolean
переменная может быть выведена в соответствии с JLS 8, потому что в контекстное задание цели типа Boolean
lets T
выводится как Boolean
, действительно. Здесь все компиляторы согласны.
Что касается исходного случая, JLS 8 не классифицирует условие if-оператора как контекстное задание. Вне контекстов назначения или вызова вызов не является рассматривается как выражение poly, но как автономное выражение (JLS 15.12 1-й пуля). Автономные выражения не имеют целевого типа. Без вывода целевого типа в Java 8 возвращается к выводу T
to Object
.
команда Eclipse имеет запрошено разъяснение в этой связи даже до Java 8 GA. К сожалению,в результате выпуска остается нерешенным до сегодняшнего дня.
Ergo: JLS и наблюдаемое поведение javac
Не согласен. вероятно, JLS-это объект, который должен быть исправлен.
обновление: JLS не собирается меняться (подтверждено по частной электронной почте), поэтому принятие программы является ошибкой в javac
.