0

I am used to java generics, e.g.

class B {}
class A<T extends B> {
  T t;
  T getT() {
    return t;
  }
}

Now, what exactly is the meaning in the following piece of code in this context?

class C {
  A<?> a;
  A<?> getA() {
    return a;
  }
}

The code compiles, but I wonder why the compile is fine with using A<?>? I would expect the compiler to complain that A must be used in the same way either on the attribute level (a1) or on the class level (a2):

class C<T extends B> {
   A<? extends B> a1;
   A<? extends B> getA1() {
     return a1;
   };

  A<T> a2;
  A<T> getA2() {
    return a2;
  }
 }

So my guess is that A<?> is only syntactic sugar, but the meaning is equal to A<? extends B>? However, many answers on stack overflow regarding the notation Something<?> means Something<? extends Object> which then would mean that all those answers are wrong?

But it is not possible to assign a A<?> typed variable to one of type A<? extends B>, which makes clear that the compiler is unaware of the fact that it is impossible to create an A<X> where X is not a subclass of B.

Theoretical, the A<?> just means unknown type argument, but the compiler should still know that the type argument must be a subclass of B because of the type parameter definition of A. But it seems that the compiler does not take into account this? Why?

Stuck
  • 11,225
  • 11
  • 59
  • 104
  • Then the example should not compile, but it does. – Stuck Jan 07 '21 at 08:44
  • Oh I looked at the wrong example, if it is the second code block you have a problem with then I think > is the same as <> or not using any <>, and it uses the most general class that is valid in the context (class B), so you are right. –  Jan 07 '21 at 08:48
  • @tibetiroka Only using `?` is the same as using `? extends [upper bound]`. In this case the upper bound of `T` is `B` and so `?` is the same as `? extends B`. – Slaw Jan 07 '21 at 09:12
  • That is what I meant, sorry if it wasn't understandable. –  Jan 07 '21 at 09:13
  • @tibetiroka Wish I could find where in the JLS this is explained, but I'm having trouble finding it or I'm not understanding the part that does explain it. Though I expect it's explained somewhere in [§4.5.1](https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.5.1). – Slaw Jan 07 '21 at 09:22
  • 1
    I couldn't find it either, but it is the logical choice. If you use a wildcard with no custom upper bounds, then it would accept all objects. However, when you defined the type in the class you gave it an upper bound. This means that any object would be casted to that type, so no objects outside the original bounds can be accepted, even if the specified wildcard would do so. From this it is clear that when the > wildcard is replaced with extends OriginalLimit> (assuming it is not the same for the compiler), you only move the required typecasts, causing no issues. –  Jan 07 '21 at 09:34
  • My other guess is that the compiler is fine with the `? extends Object` interpretation because it is local to the class definition (read: "In this class I don't care, it works on any generic type"). – Stuck Jan 07 '21 at 09:41
  • Have you seen this? https://stackoverflow.com/questions/9921676/what-does-class-mean-in-java and this one? https://www.quora.com/What-does-mean-in-java-27 – HoRn Jan 07 '21 at 12:05
  • @HoRn they do not elaborate on the relationship (if it even exists..) between unknown types during usage as argument and the generics definitions in the type parameter of a class definition. This question is about that relationship (from a compilers perspective). – Stuck Jan 07 '21 at 13:05
  • I elaborated a little more what the question is. – Stuck Jan 07 '21 at 13:15

0 Answers0