0

Here is a pathological generics example in Java. What is going on here?

public abstract class Foo<X> {

    private List<String> stuff;

    public List<String> getStuff() {
        return stuff;
    }

    public void setStuff(List<String> stuff) {
        this.stuff = stuff;
    }
}

Then I created a subclass, but not I did not specify the type bound, which should make it object.

public class Bar extends Foo {

    public Bar() {
        setStuff(new ArrayList<>());
    }

    public void whatIsGoingOnHere() {

        for(String thing : getStuff())
            System.out.println("Why is this a compiler error???");
    }
}

Why is this a compiler error?

mobiusinversion
  • 343
  • 1
  • 6
  • 17

1 Answers1

-2

You call setStuff(new ArrayList<>());. Here ArrayList<> isn't not bound, it is inferred by the compiler if it can. And it can as setStuff is setStuff(List<String>). So the compiler knows it is a ArrayList<String> and uses (infers) that.

Your loop iterates over an List<String> as returned by the getStuff() method, so defining the thing as a String (or any super class or interface) will be okay for the compiler.

The base class does have an X type, but it doesn't matter as your stuff list is declared with a type. Only if you would define stuff as an List<X> it would matter what the subclass defined for X.

M. le Rutte
  • 3,525
  • 3
  • 18
  • 31