-1

Let's say I've got this function:

Table<Record> tableOfRecord() {}

And a type TableRecord<R extends TableRecord> extends Record. And I have this other function:

<R extends TableRecord<R>> Table<R> table(Table<R> table, String filtered) {
    // ...
    return (Table<R>) tableOfRecord();
}

The above fails to compile:

error: incompatible types: Table<Record> cannot be converted to Table<R>

However, this compiles and runs fine:

return (Table<R>) ((Table<?>) tableOfRecord());

I am not sure why this is allowed, but the previous example is not.

Rohan Prabhu
  • 7,180
  • 5
  • 37
  • 71
  • I don't know. But neither is semantically correct, AFAICS - a `Table` is not a `Table` unless `R` is `Record`, which is impossible here. – Oliver Charlesworth Jul 02 '16 at 11:36
  • 1
    Look at your compiler warnings. It's shouting "unchecked cast". >hat you're doing is almost equivalent to `return (Integer) ((Object) "hello");` http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p – JB Nizet Jul 02 '16 at 11:38
  • Most generic information is erased at runtime. The JVM sees a cast of ```Table``` to ```Table```, and can not confirm that this cast is actually type-safe (which it actually is not). Hence the unchecked cast warning you get when casting generics. – Jorn Vernee Jul 02 '16 at 12:40

1 Answers1

0

It is illegal to cast from Table<Record> to Table<R> because it can be proven at compile time that no object can be both Table<Record> and Table<R>, and thus the cast is guaranteed to be incorrect. It is illegal to write a cast that can be proven at compile time to be incorrect.

(Table<R>)(Table<?>)tableOfRecord() is a sequence of two separate casts, one from type Table<Record> to Table<?>, and one from Table<?> to Table<R>, each of which is legal because each cast, by itself, is not known to be incorrect at compile-time.

newacct
  • 119,665
  • 29
  • 163
  • 224