We are currently in the process of migrating an application from Java 7 to Java 8. After fixing a some compilation issues, I stumbled upon an issue similar to the following question: ClassCast Error: Java 7 vs Java 8.
To summarise, here is a sample code that shows the issue:
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
}
}
The idea was that we would thrust that the caller knows the expected type, and this would avoid him an explicit cast (I don't say this was a good idea…). In a lot of cases, the caller just expects an Object
so there was no implicit cast at all.
As stated in the question above, the String.valueOf
example worked fine in Java 7 because there was no type inference, hence Object
was assumed. Now in Java 8, the compiler chooses the most specific type (here char[]
), which causes a ClastCastException
at runtime.
The problem is that we have around 350 calls of this getVal
method. Is there a way to detect overloaded method calls that would differ between Java 7 and Java 8? I.E. detect when the Java 8 compiler would select a different method from the Java 7 compiler.
You will get compile time error as The method foo(Object) is ambiguous for the type Test because both String and Integer class have Object as parent class and there is no inheritance. So java compiler doesn't consider any of them to be more specific, hence the method ambiguous call error.
Ambiguity errors occur when erasure causes two seemingly distinct generic declarations to resolve to the same erased type, causing a conflict. Here is an example that involves method overloading.
A better alternative would be:
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(T param) {
// do some computation based on param...
return param; // actual return type only depends on param so the caller knows what to expect
}
}
which will work in both Java 7 and Java 8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With