7

The following code compiles both test methods using javac in JDK7 but JDK8 will only compile willCompile method.

The error for willNotcompile is: "The method method(Class<T>) in the type Klasa is not applicable for the arguments (Class)."

@Test
public void willCompile() throws InstantiationException, IllegalAccessException {
    Class klass = getObject(Class.class);
    method(klass);
}

@Test
public void willNotCompile() throws InstantiationException, IllegalAccessException {
    method(getObject(Class.class));
}

<T> ResponseEntity<T> method (Class<T> klasa) {
    return new ResponseEntity<T>(HttpStatus.OK);
}
public static <T> T getObject(Class<T> clazz) throws IllegalAccessException, InstantiationException {
    return clazz.newInstance();
} 
user3364192
  • 3,783
  • 2
  • 21
  • 30
  • 2
    The `willCompile()` is using rawtypes, this is only supported for old code – Ferrybig Feb 05 '16 at 09:59
  • 2
    [What is a raw type and why shouldn't we use it?](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Tunaki Feb 05 '16 at 10:05
  • 1
    [target typing in nested invocation and raw types](http://stackoverflow.com/a/26285613/2711488) – Holger Feb 05 '16 at 12:17
  • Which jdk version did you use? Actually, all JDKs, I tested, do compile this code, of course, not without warnings. It would be a different story, if your code expected a certain `ResponseEntity` result type. – Holger Feb 05 '16 at 17:37

1 Answers1

6

The above compiles because it is using rawTypes.

The bottom one doesn't because your method only accepts a Class<T>, but you gave it a Class. Using reflection, you cannot specify the generic types of a class, so getObject will return a raw Class object.

The only fix for the problem is casting the return result.

method((Class<?>)getObject(Class.class));

But while this solution solves the runtime problem you still get problems with the fact that you cannot create new instances of Class.

JDK 7 was less strict in this comparison and casted the return result Class into a Class<?> behind the scenes so the code was allowed to compile.

According to Holger JDK 7 turns off generics types for the whole lines, and uses raw types for the return result, meaning that method gets a Class and returns a ResponseEntity.

Ferrybig
  • 18,194
  • 6
  • 57
  • 79
  • Correct, apart from the fact that `getObject()` doesn't return raw Class object but the instance of some object. So although compile is fine (you should be given warning at least), it will fail in runtime anywya. – Zbynek Vyskovsky - kvr000 Feb 05 '16 at 10:08
  • thanks. I know that you cannot create new instance of class (it will throw exception), but it was just a quick implementation to check the compilation rules not runtime. – user3364192 Feb 05 '16 at 10:09
  • 1
    Actually, Java 7 didn’t cast `Class` to `Class>`, it turned off generic type checking for the entire expression, using raw types throughout the operation. Hence, you could get away with even more generic errors in the subsequent usage when the input is a raw type. – Holger Feb 05 '16 at 12:21