请输入您要查询的百科知识:

 

词条 Wildcard (Java)
释义

  1. Covariance for generic types

  2. Wildcard as parameter type

  3. Bounded Wildcards

  4. Object Creation with Wildcard

  5. Example: Lists

  6. See also

  7. References

The wildcard ? in Java is a special type parameter that controls the type safety of the use of generic (parameterized) types. It can be used in variable declarations and instantiations as well as in method definitions, but not in the definition of a generic type.[1][2] This is a form of use-site variance annotation, in contrast with the definition-site variance annotations found in C# and Scala.

Covariance for generic types

Unlike arrays (which are covariant in Java), different instantiations of a generic type are not compatible with each other, not even explicitly: With the declaration Generic superGeneric; Generic subGeneric; the compiler would report a conversion error for both castings (Generic)superGeneric and (Generic)subGeneric.

This incompatibility may be softened by the wildcard if ? is used as an actual type parameter: Generic is the abstract supertype for all parameterizarions of the generic type. This allows objects of type Generic and Generic to be safely assigned to a variable or method parameter of type Generic. Using Generic allows the same, restricting compatibility to Supertype and its children. Another possibility is Generic, which also accepts both objects and restricts compatibility to Subtype and all its parents.

Wildcard as parameter type

In the body of a generic unit, the (formal) type parameter is handled like its upper bound (expressed with extends; Object if not constrained). If the return type of a method is the type parameter, the result (e.g. of type ?) can be referenced by a variable of the type of the upper bound (or Object). In the other direction, the wildcard fits no other type, not even Object: If ? has been applied as the formal type parameter of a method, no actual parameters can be passed to it. However, objects of the unknown type can be read from the generic object and assigned to a variable of a supertype of the upperbound.

class Generic {

private T t;

void write(T t) {

this.t = t;

}

T read() {

return t;

}

}

...

Generic concreteTypeReference = new Generic();

Generic wildcardReference = concreteTypeReference;

UpperBound ub = wildcardReference.read(); // Object would also be OK

wildcardReference.write(new Object()); // type error

wildcardReference.write(new UpperBound()); // type error

concreteTypeReference.write(new UpperBound()); // OK

Bounded Wildcards

A bounded wildcard is one with either an upper or a lower inheritance constraint. The bounds can be both class and interface types. Upper bounds are expressed using the extends keyword and lower bounds using the super keyword. An upper bound on a wildcard must be a subtype of the upper bound on the type parameter it is assigned.

Genericextends SubtypeOfUpperBound> referenceConstrainedFromAbove;

This reference can hold any instantiation of Generic with an actual type parameter of SubtypeOfUpperBound's subtype. A wildcard that does not have an upper bound is effectively the same as one that has the constraint extends Object, since all types implicitly extend Object. A wildcard with a lower bound

Genericsuper SubtypeOfUpperBound> referenceConstrainedFromBelow;

can hold instantiations of Generic with any type that is both a subtype of UpperBound and a supertype of SubtypeOfUpperBound. The type bounds are trivial examples that conform.

Object Creation with Wildcard

No objects may be created with a wildcard type parameter: new Generic() is forbidden because Generic is abstract.[3] In practice, this is unnecessary because if one wanted to create an object that was assignable to a variable of type Generic, one could simply use any arbitrary type (that falls within the constraints of the wildcard, if any) as the type parameter.

However, new List>() is allowed, because the wildcard is not a parameter to the instantiated type List. The same holds for new List>().

An array object that is an array of a parameterized type can only parameterized by an unconstrained (i.e. with an unbound wildcard type parameter) type as the component type: new Generic[20] is correct, while new Generic[20] is not.

For both cases, using no parameters is another option. This will generate a warning since it is less type-safe (see Raw type).

Example: Lists

In the Java Collections Framework, the class List represents an ordered collection of objects of type MyClass.

Upper bounds are specified using extends:

A List is a list of objects of some subclass of MyClass, i.e. any object in the list is guaranteed to be of type MyClass, so one can iterate over it using a variable of type MyClass[4]

public void doSomething(List list) {

  for(MyClass object : list) { // OK    // do something  }

}

However, it is not guaranteed that one can add any object of type MyClass to that list:

public void doSomething(List list) {

  MyClass m = new MyClass();  list.add(m); // Compile error

}

The converse is true for lower bounds, which are specified using super:

A List is a list of objects of some superclass of MyClass, i.e. the list is guaranteed to be able to contain any object of type MyClass, so one can add any object of type MyClass:

public void doSomething(List list) {

  MyClass m = new MyClass();  list.add(m); // OK

}

However, it is not guaranteed that one can iterate over that list using a variable of type MyClass:

public void doSomething(List list) {

  for(MyClass object : list) { // Compile error    // do something  }

}

In order to be able to do both add objects of type MyClass to the list and iterate over it using a variable of type MyClass, a List is needed, which is the only type of List that is both List and List.[5]

The mnemonics PECS (Producer Extends, Consumer Super) from the book Effective Java by Joshua Bloch gives an easy way to remember when to use wildcards (corresponding to Covariance and Contravariance) in Java.

See also

  • Bounded quantification
  • Covariance and contravariance (computer science)
  • Generics in Java#Type wildcards section explains lower and upper wildcard bounds

References

1. ^{{citation|title=Generics in the Java Programming Language|url= http://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf|author=Gilad Bracha|date=June 2004|section=4. Wildcards|accessdate=6 March 2016}}
2. ^{{citation|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.2|title=The Java Language Specification|section=8.1.2 Generic Classes and Type Parameters|publisher=Oracle|accessdate=6 March 2016}}
3. ^{{citation|title=The Java Language Specification|section=Class Instance Creation Expressions|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.9|publisher=Oracle}}
4. ^Inheritance (object-oriented programming)
5. ^Java syntax(Generics)
  • The Java Language Specification, Third Edition (Sun), {{ISBN|978-0-321-24678-3}} http://java.sun.com/docs/books/jls/
  • Java Tutorials, Lesson Generics http://download.oracle.com/javase/tutorial/java/generics/index.html
  • Capturing Wildcards, http://bayou.io/draft/Capturing_Wildcards.html
  • Typkompatibilität in Java http://public.beuth-hochschule.de/~solymosi/veroeff/typkompatibilitaet/Typkompatibilitaet.html#Joker (in German)
{{DEFAULTSORT:Wildcard (Java)}}

3 : Java (programming language)|Polymorphism (computer science)|Articles with example Java code

随便看

 

开放百科全书收录14589846条英语、德语、日语等多语种百科知识,基本涵盖了大多数领域的百科知识,是一部内容自由、开放的电子版国际百科全书。

 

Copyright © 2023 OENC.NET All Rights Reserved
京ICP备2021023879号 更新时间:2024/9/24 3:22:38