Using generics with wildcards does not allow using methods with generic as a parameter
If i declare a generic class as something like
public class Driver<V extends Car>
where Car is an interface.
Then, I use it with something like this:
Driver<?> driver = new Driver<Chevrolet>();
I don't want to specify a specific implementation of car as the generic.
W开发者_C百科hy is it that I cannot call methods implemented in driver that uses the generic class as the parameter?
For example if Driver has a method like
public void drive(V vehicle)
It does not allow me to call that with my instance of driver (Driver<?>
).
Because the compiler doesn't know what type of argument driver.drive(? vehicle)
will accept. Should it take a Chevrolet, a Honda, or some other type?
For more details you might find Gilad Bracha's Generics Tutorial helpful.
What is the purpose of your drive() method. Does the vehicle
parameter need to be typed to the specific subtype of Car? Would it be more appropriate for it to simply accept a Car
?
The following was part of my original answer, but discussion in the comments proved that it was incorrect. I'm leaving it here so the comments aren't orphaned.
Try declaring your method like this:
public <T extends V> void drive(T vehicle)
and see if that works better for you.
The question is vague, but I believe this excerpt from Angelika Langer's Java Generics FAQ answers it:
Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?
It depends on the kind of wildcard.
Using an object through a reference variable of a wildcard parameterized type is restricted. Consider the following class:
Example (of a generic class):
class Box<T> { private T t; public Box(T t) { this.t = t; } public void put(T t) { this.t = t;} public T take() { return t; } public boolean equalTo(Box<T> other) { return this.t.equals(other.t); } public Box<T> copy() { return new Box<T>(t); } }
When we use a reference variable of a wildcard instantiation of type Box to access methods and fields of the referenced object the compiler would reject certain invocations.
Example (of access through a wildcard parameterized type):
class Test { public static void main(String[] args) { Box<?> box = new Box<String>("abc"); box.put("xyz"); // error box.put(null); // ok String s = box.take(); // error Object o = box.take(); // ok boolean equal = box.equalTo(box); // error equal = box.equalTo(new Box<String>("abc")); // error Box<?> box1 = box.copy(); // ok Box<String> box2 = box.copy(); // error } }
Essentially ?
has less information for the generic type system, and thus to enforce typesafety certain invokations must be rejected, because they're not typesafe.
A Box<?>
may be a Box<Integer>
, a Box<String>
, or even a Box<Box<?>>
. Thus given a Box<?> box
, box.put("xyz")
must be rejected.
References
- Angelika Langer's Java Generics FAQ
- Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?
Related questions
- How can I add to
List<? extends Number>
data structures?
精彩评论