1

Hi I am playing with generics a suddenly found a issue where i am getting compile time error :

Type mismatch: cannot convert from element type Object to String

import java.util.*;

public class A<T> {
    private final T first;

    public A(T first) {
        this.first = first;

    }
    public List<String> stringList() {
        return Arrays.asList(String.valueOf(first));
    }

    public static void main(String[] args) {
        A p = new A<Object>("TEST");
        for (String s : p.stringList())
            System.out.print(s + " ");
    }
}

I am unable to understand this behavior as String is Object and compiler should understand that, can someone explain this?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
T-Bag
  • 10,916
  • 3
  • 54
  • 118
  • Why it is marked as duplicate....its not a bug..:( – T-Bag Apr 29 '17 at 14:35
  • 2
    Using a raw type in the type declaration makes all generics in the type raw, even if they are unrelated to the omitted type constraint. – Andy Turner Apr 29 '17 at 14:36
  • I think the relevant section from the linked question is titled "**A raw type is the erasure of that type**" which shows what looks like a very similar example – UnholySheep Apr 29 '17 at 14:38
  • 1
    Use this to make it compile: `A p = new A<>("TEST");` – Robin Topper Apr 29 '17 at 14:38
  • @RobinTopper---It is working fine thanks could you please explain me why it is compiling now – T-Bag Apr 29 '17 at 14:39
  • 2
    ShowStopper - Because declaring it properly means you're not using a raw type `A` anymore. – T.J. Crowder Apr 29 '17 at 14:40
  • @AndyTurner: So by using the raw type `A`, it means that `stringList`'s return type is just `List` from the compiler's perspective, not `List`, is that correct? – T.J. Crowder Apr 29 '17 at 14:42
  • So what I understand is compiler interprets the program as if this method returned the raw typeList. While List implements the parameterized type Iterable, List implements the raw type Iterable. Where Iterable has an iterator method that returns the parameterized type , Iterable has an iterator method that returns the raw type Iterator. Where the next method of Iteratorreturns String, the next method of Iterator returns Object. Therefore, iterating overp.stringList() requires a loop variable of type Object, which explains the compiler's error message – T-Bag Apr 29 '17 at 14:43
  • 1
    @T.J.Crowder yes. – Andy Turner Apr 29 '17 at 14:43
  • 1
    @AndyTurner Thanks. I added that other dupe, btw. – T.J. Crowder Apr 29 '17 at 14:44
  • @T.J.Crowder--Is it really a duplicate ...?? – T-Bag Apr 29 '17 at 14:44
  • Yes, it is a duplicate. – Tom Apr 29 '17 at 14:46
  • okies...:( by the way thanks guys – T-Bag Apr 29 '17 at 14:47
  • 4
    @ShowStopper: Yes, of both of those. The central issue is that by just using `A p` instead of `A p`, **all** generic type parameters for `p` are erased entirely. So it's as though your `stringList` were declared `List stringList()` (the raw type `List`). So `for (String s : p.stringList())` is asking to use `Object` (the element type of the raw type `List`) as a `String`. You can't do that implicitly. – T.J. Crowder Apr 29 '17 at 14:47

0 Answers0