0

Class is defined as Header<Field<Column<Content<?>>>>{}, variable declaration is Header<Field<Column<Content<String>>>> aHeader. This gives a BoundMismatch error. Changing declaration to Header<Field<Column<Content<?>>>> aHeader; removes the error but loses type information and therefore not desired. What is the strategy to make this work? PS: The class definition has to retain the ?.

Dudus
  • 25
  • 8
  • 2
    What do you mean "loses type information"? It doesn't look like you're losing anything. Anyway, the short answer is, you can't. Because a `Column>` simply _isn't_ a `Column>`, even though it seems like it should be. – Dawood ibn Kareem Jun 06 '18 at 01:48
  • What do you mean "loses type information"? . . . If i instantiated Content> someCont=Content(); then i did someCont.getContent(); I would get Object, not String. – Dudus Jun 06 '18 at 02:03

1 Answers1

0

A variable of type Header<Field<Column<Content<String>>>> Can only ever contain a Header<Field<Column<Content<String>>>> It has no upper or lower bounds, it can only contain Header<Field<Column<Content<String>>>>

Header<Field<Column<Content<?>>>> Represents a Header<Field<Column<Content<**unknown**>>>>

How can you be sure that when you fetch the string back from the unknown variant, that you will always get a string? You can't. Therefore you get the error above to warn you that you can not assign a wildcard collection to a string.

Collections are both producers, and consumers.

As a general rule of thumb, PECS: Producers Extend, Consumers Supers.

Which is a mnemonic device to remember the bounds.

However a Collection acts as both, it can have things added as well as popped. So, generally they are restricted to a single type.

Can you add a string to a collection of ?

No. the wildcard is a type restriction saying it could be a collection of any type. It does NOT mean that it can contain every type.

So what are wildcards good for? https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

Shows some good examples, They can be used to restrict the types of the collection itself, as opposed to defining the collection as able to take any object.

e.g.

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

Is a compile error, because the only guarantee you have, is that shapes is a collection of things that extend Shape, it could be a List<Circle>!

Where as

public void addRectangle(List<Shape> shapes) {
    shapes.add(0, new Rectangle());
}

Works fine, as Rectangle is a shape, and shapes can now contain any shape.

What is the strategy to make this work?

Keeping your restriction of "PS: The class definition has to retain the ?." I see no way of making it work, aside from explicit casting.

As long as the class definition contains a wildcard, you can never be sure of what type it is. Which is also the reason why they cannot be used as type parameters of classes.

What you may be interested in, is just normal plain Generic Type Parameters

Ryan Leach
  • 4,262
  • 5
  • 34
  • 71