Say I've an interface "Generic" -
public interface Generic<T> {
public T echo(T input);
public List<String> hello();
}
And an implementation class say GenericImpl with any trivial implementation. Now, when I create an instance of Generic and invoke hello, it returns me a List and not a List<String> -
Generic g1 = new GenericImpl();
for (String msg : g1.hello()) { // Gives compilation error :
// Type mismatch, cannot convert from element type Object to String
...
Even in eclipse, when I hover on g1.hello, it shows me the return type as List and not List<String>.
This does not happen if I use a normal interface (without generic <T> ). Any suggestions on how to make it work / why does it happen ?
This has to do with raw types. First, a definition
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
You are using such a raw type here
Generic g1 = new GenericImpl();
since Generic has no type argument. Then the JLS also states
The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.
Therefore, when using the raw type Generic, the hello() method has a return type of List which is the erasure of List<String>. As such, the return type of List#iterator() is Iterator and the return type of Iterator#next() is Object, a type which cannot be converted to String.
You will need to use a type argument for your g1's type declaration so that it is not considered a variable of a raw type.
You have to define the interface as generic (with a type).
Generic<YourGenericType> g1 = new GenericImpl();
By ommitting the generic definition, it will be considered a "raw type". Raw types will return Objects instead. More information on raw types can be found here.
public class Test {
public static void main(String[] args) {
Generic<Integer> obj = new GenericImpl();
System.out.println(obj.echo(5));
for(String s : obj.hello()){
System.out.println(s);
}
}
}
interface Generic<T> {
public T echo(T input);
public List<String> hello();
}
class GenericImpl implements Generic<Integer> {
@Override
public Integer echo(Integer input) {
return input;
}
@Override
public List<String> hello() {
return new ArrayList<String>(Arrays.asList("lala", "lolo"));
}
}
Output:
5
lala
lolo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With