Generics with sequels

IN:

public class Organic<E> { void react(E e) { } static void main(String[] args) { Organic<? extends Elem> compound = new Organic<Elem>(); compound.react(new Elem()); } } class Elem {} 

Why does the following compilation error occur?

The react(capture#1-of ? extends Elem) method in type Organic<capture#1-of ? extends Elem> Organic<capture#1-of ? extends Elem> not applicable for arguments ( Elem )

0
source share
3 answers

From http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

A list is an example of a limited template.? denotes an unknown type, as does the wildcard that we saw earlier. However, in this case, we know that this unknown type is actually a subtype of Shape. (Note: this may be the form itself or some subclass; it should not literally expand the form.) We say that Shape is the top border of the template.

There is, as usual, a price for the flexibility of using wildcards. This price is that it is now illegal to write in figures in the body of the method. For example, this is not valid:

 public void addRectangle(List<? extends Shape> shapes) { // Compile-time error! shapes.add(0, new Rectangle()); } 

You must understand why the above code is not allowed. Is there a second parameter type for shape.add ()? extends Shape is an unknown subtype of Shape. Since we don’t know what it is, we don’t know if it is a supertype of Rectangle; it may or may not be such a supertype, so it is unsafe to pass a Rectangle.

In particular, speaking of your decision, you cannot cause a reaction with an object of type Elem , like with a type of Organic<? extends Elem> Organic<? extends Elem> , which you can legally assign compound = new Organic<ElemSubClass>() - and then react will cause a compilation error, since you cannot call it passing a superclass object.

+1
source

changed your reactas method below, it will work:

 void react(Elem e) { } 
0
source

"? extends SomeClass' is used to define common types when you want to allow the user to pass only SomeClass or its subclasses as a general parameter. This means that you can do this:

 public class Organic<E extends Elem> { void react(E e) { } 

if you want Organic to be parameterized by subclasses of Elem. In the main method, you can do something like this:

  Organic<Elem> compound = new Organic<ElemOrAnyElemSubclass>(); 

as I know there is no need to use

 Organic<? extends Elem> 

in the body of the method.

Integer code:

 public class Organic<E extends Elem> { void react(E e) { } static void main(String[] args) { Organic<Elem> compound = new Organic<Elem>(); compound.react(new Elem()); } } class Elem {} class ElemSubClass extends Elem {} // if you need 

In addition, you must use the same general types on both the left and right sides of the expression. This is Ilhal: Organic Composition = new Organic ();

Not sure if this is what you wanted, but hope this helps.

0
source

Source: https://habr.com/ru/post/1442925/


All Articles