Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCast error: Java 7 vs Java 8

Is this a bug or feature? The following code runs fine in Java 7 but throws an exception in Java 8:

The last command throws a ClassCast exception in Java8, all the "equivalent" commands above work the same way.

The problem, I think, is that in Java 8, the compiler decides to use String.value(char[]) on the last line instead of String.value(Object) as in Java 7. I would think this should behave the same way for backward compatibility. Am I missing something?

Note: As Marko suggested this is probably related to target type inference introduced in Java 8.

public class Test {     public static void main(String[] args) {         System.out.println( getVal().getClass());  // String          System.out.println( String.valueOf(Test.<Object>getVal()) );   // "abc"          Object obj = getVal();         System.out.println( String.valueOf(obj) );  // "abc"          System.out.println( String.valueOf(getVal()) ); // 7: "abc", 8: Exception      }      // returns a string for simplicity; imagine that given a field, it fetches values from a database     @SuppressWarnings("unchecked")     public static <T> T getVal() {         return (T) "abc";     } } 

Result in Java 7:

class java.lang.String abc abc abc 

Result in Java 8:

class java.lang.String abc abc Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to [C     at Test.main(Test.java:11) 

(Note: [C is an array of chars)

Both Java's are on windows:

java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) Client VM (build 24.45-b08, mixed mode, sharing)  java version "1.8.0_05" Java(TM) SE Runtime Environment (build 1.8.0_05-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode) 
like image 595
Jirka Avatar asked Apr 18 '14 14:04

Jirka


People also ask

Is Java 8 better than java7?

Key differences between Java 7 vs Java 8Java 8 is the next largest Java 7 upgrade, which has some important features and enhancements in the Java model. JVM supports dynamic languages plus minor language improvements are one of the most notable features of Java's 7.

What are the advantages of Java 8 over Java 7?

Java 8 also gets a new and improved Date/Time API, an enhanced JavaScript engine, new streaming API. Concurrent accumulators, secure random generation, and much more. Java 7 had improved class-loader architecture, enhanced Managed Beans, multiple exceptions handling support, etc.

Can I have Java 7 and 8 installed?

Java SE 8 is binary-compatible with Java SE 7 except for the incompatibilities listed below. Except for the noted incompatibilities, class files built with the Java SE 7 compiler will run correctly in Java SE 8. Class files built with the Java SE 8 compiler will not run on earlier releases of Java SE.


Video Answer


1 Answers

String.valueOf is a heavily overloaded method and you are using it in a context where the argument type must be inferred from the context. On the other hand, the rules of type inference have received a significant overhaul in Java 8; most notably target type inference has been much improved. So, whereas before Java 8 the method argument site did not receive any inference, defaulting to Object in your case, in Java 8 the most specific applicable type was inferred, in this case char[].

However, keep in mind that in both cases the idiom you used is essentially broken so the change in compiler output should perhaps be designated as a "pitfall", but not a "bug".

The unchecked cast is unfortunately sometimes unavoidable, but I can't think of any case where it makes sense to infer the type itself (as opposed to a type parameter) of something which is not created reflectively from a Class object. Therefore you are not likely to actually find yourself in the position shown here, where you infer the type based on the acceptable argument types on the call site. Moreover, it is certainly broken to do this with an overloaded method, leaving the choice of argument type to inference. This can only work "by accident".

like image 137
Marko Topolnik Avatar answered Sep 21 '22 04:09

Marko Topolnik