4

So I've been reading through the Generics tutorial offered by Oracle here: http://docs.oracle.com/javase/tutorial/java/generics/

And I've tried running my own example to make sure I understand how to use Generics. I have the following code:

import java.util.*;

public class Generics {
    class NaturalNumber {
        private int i;

        public NaturalNumber(int i) { this.i = i; }
    }
    class EvenNumber extends NaturalNumber {
        public EvenNumber(int i) { 
            super(i);
        }
    }    
    public static void main(String[] args) {
        Collection<? extends NaturalNumber> c = new ArrayList<>();
        c.add(new EvenNumber(2)); //this line produces a compile time error     
    }
}

My goal is to be able to add any object which is a subtype of NaturalNumber to the Collection c. I'm not sure why this doesn't work and reading through Oracle's tutorial hasn't enlightened me either.

4

3 回答 3

7

When you have ? extends NaturalNumber, the parameter could be some other subclass of NaturalNumber that is in no way related to EvenNumber. For instance,

Collection<? extends NaturalNumber> c = new ArrayList<OtherNaturalNumber>();

is valid if OtherNaturalNumber extends NaturalNumber.

Consequently, you are not able to add an EvenNumber instance to the list. You can just use this declaration:

Collection<NaturalNumber> c = new ArrayList<>();

which will allow you to add any NaturalNumber instance (including an EvenNumber).

On another note, you probably meant to make those nested classes static (or don't nest them at all).

于 2013-08-21T02:45:51.647 回答
1

First Collection<? extends NaturalNumber> should just be Collection<NaturalNumber>. Instances of EvenNumber (or any NaturalNumber or a subtype of NaturalNumber) can be put into the collection this way.

Essentially Collection<? extends NaturalNumber> says that the type of the type parameter to Collection extends NaturalNumber. So say that class OddNumber extends NaturalNumber, then the type of Collection's type parameter could be OddNumber which EvenNumber cannot be safely cast to.

However there is another compiler error. To be used in the static context or main(String[]) each of the inner classes NaturalNumber and EvenNumber need to have the modifier static placed on each class declaration.

于 2013-08-21T02:49:16.610 回答
0

Your problem is that you've told the compiler that the Collection's element type can be any type that extends NaturalNumber, but then you tried to insert an object into it. As far as the compiler knows, c is a Collection<OddNumber>, and you just added an EvenNumber!

于 2013-08-21T02:46:13.523 回答