В настоящее время мы находимся в процессе переноса приложения с Java 7 на Java 8. После исправления некоторых проблем с компиляцией я наткнулся на проблему, похожую на следующий вопрос: Ошибка ClassCast: Java 7 против Java 8.
Подводя итог, вот пример кода, который показывает проблему:
public class Test {
public static void main(String[] args) {
System.out.println(String.valueOf(getVal("xxx"))); // 7: prints the result, 8: Exception
}
@SuppressWarnings("unchecked")
public static <T> T getVal(String param) {
// do some computation based on param...
return (T) result; // actual return type only depends on param so the caller knows what to expect
}
}
Идея заключалась в том, чтобы указать, что вызывающий объект знает ожидаемый тип, и это позволит ему избежать явного приведения (я не говорю, что это была хорошая идея…). Во многих случаях вызывающий объект просто ожидает Object
, поэтому неявного приведения вообще не было.
Как указано в вопросе выше, пример String.valueOf
отлично работал в Java 7, потому что не было вывода типа, поэтому предполагалось Object
. Теперь в Java 8 компилятор выбирает наиболее конкретный тип (здесь char[]
), что вызывает ClastCastException
во время выполнения.
Проблема в том, что у нас около 350 вызовов этого метода getVal
. Есть ли способ обнаружить перегруженные вызовы методов, которые будут различаться между Java 7 и Java 8? I.E. определить, когда компилятор Java 8 выберет другой метод из компилятора Java 7.
Class<T> clazz
. Таким образом, вы можете иметь явную обработку ошибок: либо вернуть null, либо выдать какое-то более конкретное исключение. Я только что сделал это вручную, потратив полчаса. Я советую вам сделать то же самое. Я не знаю, как это автоматизировать, поэтому это не считается ответом на ваш вопрос. - person Tagir Valeev   schedule 29.05.2015@SuppressWarnings("unchecked")
… - person Holger   schedule 29.05.2015@SuppressWarnings
, он есть только в объявленииgetVal
. Таким образом, удаление этой аннотации здесь не покажет каких-либо проблемных вариантов использования. - person Didier L   schedule 01.06.2015getVal
является проблемой. Так что поиск аннотации приведет вас в нужное место. Тогда исправление подписи, конечно же, вызовет ошибки компилятора у вызывающих программ, поэтому их будет легко найти. Если вы не используете IDE, которая рефакторит подпись и вызывающие объекты за один раз, что является жизнеспособной альтернативой. Конечно, как только аннотация привела вас к проблемному методу, поиск вызывающих его функций работает даже без его изменения, если вы используете приличную IDE. Итак, необходимые инструменты имеются… - person Holger   schedule 01.06.2015Object
автоматически исправит проблемные вызовы, поэтому по иронии судьбы там не будет никаких изменений (и я, возможно, никогда не узнаю, где они были :-). - person Didier L   schedule 01.06.2015getVal
, я все равно опасаюсь, что где-то есть другие методы, которые могут быть объявлены аналогичным образом (возможно, не таким очевидным образом), которые могут вызвать ту же проблему, и их будет трудно обнаружить… - person Didier L   schedule 04.06.2015