0

I am delving more into Generics, when I feel I know, I get proved otherwise by compiler :-)

Here's source:

public class Generics3 {

    <T> void printExtends_compile_error( List<T extends Dog> t) {
        
    }

    void printExtends_correct_syntax( List<? extends Dog> t) {
        
    }

    <T> void printSuper_compile_error(List<T super Dog> t) {
        
    }


    void printSuper_correct_syntax(List<? super Dog> t) {
        
    }

class FatherOfAllAnimal{}
class Animal extends FatherOfAllAnimal{}
class Dog extends Animal {}
class Cat extends Animal {}
class Tiger extends Animal {}
class Lion extends Animal {}

class Dog1 extends Dog{}
class Dog2 extends Dog1{}
class Dog3 extends Dog2{}

The methods ending with _compile_error are compile errors - why they aren't valid? So, can I used super or extends only with wild card?

halfer
  • 19,824
  • 17
  • 99
  • 186
CuriousMind
  • 8,301
  • 22
  • 65
  • 134
  • 1
    You can only define `` with class like `class Foo{..}`, or before return type of generic method like ` T methodName(arguments){..}`. But at ` void printSuper_compile_error(List t)` you are trying to *define* `` in *argument* of `printSuper_compile_error` method which is not allowed. Only "defining" *wildcards* `>` is allowed there. Now lets wait for someone who will provide relevant specification quotes... – Pshemo Apr 16 '23 at 18:31
  • In fact, I didn't kept before method, the result was same - compilation error. – CuriousMind Apr 16 '23 at 18:34
  • List extends Dog> also valid in method argument .. this was my understanding, that instead of using ?, we can use like List – CuriousMind Apr 16 '23 at 18:37
  • 1
    I forgot to mention that you can *use* already defined `` in method arguments like ` void printExtends_compile_error( List t) {...}`. – Pshemo Apr 16 '23 at 18:37
  • 1
    As for why `` is not allowed, it is explained in your previous question: [super in Generics T super User defined class not working](https://stackoverflow.com/q/76028395). In short `` would allow *any* super type of `Dog` *which includes* `java.lang.Object`. But since all classes extend `java.lang.Object` if we write method like ` foo(T argument){..}` it would accept any `Object`, even String since code like `Object obj = "some String"; foo(obj);` would be legal. We would end up creating method like `void foo(Object argument){..}`. – Pshemo Apr 16 '23 at 18:55

1 Answers1

2

printExtends_compile_error and printSuper_compile_error are not valid is because you are trying to use bounded type parameters in a method's parameter declaration, which is not allowed in Java.

In Java, when declaring a bounded type parameter, it must be done at the class or method level, and not at the method's parameter level.

So what you want to do is

<T extends Dog> void printExtends_compile_error( List<T> t) {

}

However super may not be used as type parameter, but only as wildcard. This means, that

<T super Dog> void printSuper_compile_error(List<T> t) {

}

will still be invalid.

Cosemuckel
  • 397
  • 1
  • 8