В момента сме в процес на мигриране на приложение от 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? Т.е. открива кога компилаторът на 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