3

Why is it that a generic T cannot be used as a return type of class if T extends Class.

Example:

public class Foo<T extends Bar> {
    Bar[] array = new Bar[200];

    Optional<T> forIndex(int index) {
        return Optional.ofNullable(array[index]);
    }
}

T is required to extend Bar Which means that T should never have a casting problem, or am I mistaking this? Could somebody elaborate.

Hobbyist
  • 15,888
  • 9
  • 46
  • 98

1 Answers1

5

You got it the wrong way around. Each T is a Bar, but not each Baris a T. T is more specialized than Bar (each dachshound is a dog, but not each dog is a dachshound). This means, that return Optional.ofNullable(array[index]); tries to match a Bar on a T, which is not possible.

What you can do is making only the method generic:

public class Main {
    Bar[] array = new Bar[200];

    Optional<? super Bar> forIndex(int index) {
        return Optional.ofNullable(array[index]);
    }
}

You might want to look at Oracle's tutorial on Wildcards as well as the PECS (Producer extends - Consumer super) mnemonic


Turing85
  • 18,217
  • 7
  • 33
  • 58
  • Seems like this is just going to turn into a nasty situation with a bunch of abstract methods. `Oops:` I wrote the example in the question box :P – Hobbyist Jun 06 '15 at 19:54
  • If only generic arrays were easier to use. – Hobbyist Jun 06 '15 at 19:56
  • 1
    The erased nature of Java generics assures that arrays and generics don't mix well: arrays are covariant and retained, generics are invariant and erased. – scottb Jul 13 '15 at 22:52