Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect ambiguous method calls that would cause a ClassCastException in Java 8?

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.

like image 750
Didier L Avatar asked May 28 '15 21:05

Didier L


People also ask

What is ambiguous method call in Java?

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.

What is ambiguous error in Java?

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.


1 Answers

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.

like image 114
Shirishkumar Bari Avatar answered Oct 17 '22 05:10

Shirishkumar Bari