I was encountered this wired issue.
class Foo<R, C> {
public C fooMethod() {
Bar bar = new Bar();
Map<String, String> m = new HashMap<>();
return bar.barMethod(m);
}
}
class Bar {
public <T> T barMethod(Map<String, String> m) {
Object barObj = null;
...
return (T) barObj;
}
}
If I declare m
to be a raw type Map m = new Map()
, I get a compile error:
incompatible types: Object cannot be converted to C, where C is a type-variable.
but if m
is a typed object as declared above, then the compile error is gone.
I can't figure out why the parameter will make a different for compiler to figure out what the return type is. And to me the compiler should not think the generic type T in the Bar class example to be a Object type under any circumstances. Can some one point out where I'm wrong? Thanks in advance.
Map m = new HashMap<>();
return bar.barMethod(m); //error
The error is thrown because barMethod(Map<String, String> m)
specifically requires a Map<String, String>
. You can do a couple of things to make the compile error dissaper.
Change barMethod
parameter to a raw type.
public <T> T barMethod(Map m) {...}
OR
Cast return value to C
in the method fooMethod
return (C) bar.barMethod(m);
OR
Change the return type of the method fooMethod
to Object
public Object fooMethod()
I can't find any source in the spec but basically, because you've used the raw type Map
in place of the generic Map<String, String>
, Java converts all generic parameters (not just the Map
) to the type-erased Object
. The method signature effectively becomes:
public Object barMethod(Map<Object, Object> m)
Because barMethod
returns an Object
, and Object
is not necessarily a C
(as returned by fooMethod
), the types are incompatible. That's why this results in a compiler error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.