tags:

views:

126

answers:

5

I tried to make sure this wasn't a duplicate post, sorry if I was blind.

This is a small snippet of code taken from some of the examples that accompany the Stanford Parser. I've been developing in Java for about 4 years, but have never had a very strong understanding of what this style of code is supposed to indicate.

        List<? extends HasWord> wordList = toke.tokenize();

I'm not worried about the details of the code. What I'm confused about is what exactly the generic expression is supposed to convey, in English.

Can someone explain this to me?

Thanks!

+8  A: 
? extends HasWord

means "A class that extends HasWord." In other words, HasWord itself or any of its children... basically anything that would work with instanceof HasWord.

In more technical terms, ? extends HasWord is a bounded wildcard, covered in Item 28 of Effective Java 2nd Edition, starting on page 134. This is part of the chapter on Generics available online as a PDF.

R. Bemrose
"anything that would work with instanceof" - plus null values. Remember that null values return false for any instanceof check.
Eyal Schneider
@Eyai Schneider: I didn't know that you could use null as a generic. I guess I learn something every day.
R. Bemrose
Don't forget interfaces. The ? doesn't have to represent a class!
Mark Peters
A: 

A question mark is a signifier for 'any type'. ? alone means

Any type extending Object (including Object)

while your example above means

Any type extending or implementing HasWord (including HasWord if HasWord is a non-abstract class)

Jherico
+1  A: 

In English:

It's a List of some class that extends the class HasWord, including HasWord

In general the ? in generics means any class. And the extends SomeClass specifies that that object must extend SomeClass (or be that class).

jjnguy
+2  A: 

List<? extends HasWord> accepts any concrete classes that extends HasWord. If you have the following classes...

public class A extends HasWord { .. }
public class B extends HasWord { .. }
public class C { .. }
public class D extends SomeOtherWord { .. }

... the wordList can ONLY contain a list of either As or Bs or mixture of both because both classes extend the same parent.

limc
Not only concrete, also abstract subclasses.
bloparod
@bloparod: true... +1 for you.
limc
Not only concrete and abstract subclasses, but also sub-interfaces: `List<? extends Collection<String>> list = new ArrayList<List<String>>();`.
Mark Peters
A: 

Perhaps a contrived "real world" example would help.

At work we have rubbish bins that come in different flavours. All bins contain rubbish, but some bins are specialist and do not take all types of rubbish. So we have Bin<CupRubbish> and Bin<RecylcableRubbsih>. The type system needs to make sure I can't put my HalfEatenSandwichRubbish into either of these types, but it can go into a general rubbish bin `Bin<Rubbish>. If I wanted to talk about a Bin of Rubbish which may be a specialist so I can't put in incompatible rubbish, then that would be Bin<? extends Rubbish>.

(Note: ? extends does not mean read-only. For instance, I can with proper precautions take out a piece of rubbish from a bin of unknown speciality and later put it back in a different place.)

Not sure how much that helps. Pointer-to-pointer in presence of polymorphism isn't entirely obvious.

Tom Hawtin - tackline