ArticleslgStudy

computer science

Wildcard (Java)

Wildcard (Java) is a computer science topic covered in the lgStudy science library. This page brings together a partial reference excerpt, illustrations, worked examples, real-world applications and a short study plan, so you can understand Wildcard (Java) rather than just read about it. In short: In the Java programming language, the wildcard ? is a special kind of type argument 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.

Key takeaways

  • Wildcard (Java) belongs to computer science; place it in that map before memorising details.
  • Learn the definition first, then one example that makes the definition concrete.
  • Connect Wildcard (Java) to a quantity you can measure, compute or draw — that is where exam questions come from.
  • Reproduce the core statement of Wildcard (Java) from memory before moving on to harder problems.

Reference excerpt

In the Java programming language, the wildcard ? is a special kind of type argument 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. 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. For example, the declarations

will cause the compiler to report conversion errors for both castings (Generic<Subtype>)superGeneric and (Generic<Supertype>)subGeneric. This incompatibility can be softened by the wildcard if ? is used as an actual type parameter. Generic<?> is a supertype of all parameterizarions of the generic type Generic. This allows objects of type Generic<Supertype> and Generic<Subtype> to be safely assigned to a variable or method parameter of type Generic<?>. Using Generic<? extends Supertype> allows the same, restricting compatibility to Supertype and its children. Another possibility is Generic<? super Subtype>, 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; java.lang.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 java.lang.Object). In the other direction, the wildcard fits no other type, not even java.lang.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. Sample code for the Generic<T extends UpperBound> class:

Sample code that uses the Generic<T extends UpperBound> class:

Bounded wildcards A bounded wildcard is one with either an upper or a lower inheritance constraint. The bound of a wildcard can be either a class type, interface type, array type, or type variable. Upper bounds are expressed using the extends keyword and lower bounds using the super keyword. Wildcards can have at most one bound - either an upper bound or a lower bound, but not both.

Upper bounds An upper bound on a wildcard must be a subtype of the upper bound of the corresponding type parameter declared in the corresponding generic type. An example of a wildcard that explicitly states an upper bound is Generic<? extends SubtypeOfUpperBound> referenceConstrainedFromAbove; This reference can hold any parameterization of Generic whose type argument is a subtype of SubtypeOfUpperBound. A wildcard that does not explicitly state an upper bound is effectively the same as one that has the constraint extends Object, since all reference types in Java are subtypes of java.lang.Object.

Lower bounds A wildcard with a lower bound, such as Generic<? super SubtypeOfUpperBound> referenceConstrainedFromBelow; can hold any parameterization of Generic whose any type argument is both a subtype of the corresponding type parameter's upper bound and a supertype of SubtypeOfUpperBound.

Object creation with wildcard No objects may be created with a wildcard type argument: for example, new Generic<?>() is forbidden. 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 argument. However, new ArrayList<Generic<?>>() is allowed, because the wildcard is not a parameter to the instantiated type java.lang.ArrayList<E>. The same holds for new ArrayList<List<?>>(). In an array creation expression, the component type of the array must be reifiable as defined by the Java Language Specification, Section 4.7. This entails that, if the component type of the array has any type arguments, they must all be unbounded wildcards (wildcards consisting of only a ?). For example, new Generic<?>[20] is correct, while new Generic<SomeType>[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 In the Java Collections Framework, the class java.util.List<E> represents an ordered collection of objects of type E. Upper bounds are specified using extends: A List<? extends MyClass> 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

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

The converse is true for lower bounds, which are specified using super: A List<? super MyClass> 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:

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

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<MyClass> is needed, which is the only type of List that is both List<? extends MyClass> and List<? super MyClass>. 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.

Type constraints in other languages The closest equivalent feature to Java wildcard type parameters are Scala type wildcards; also denoted using a ? since Scala 3 (in Scala 2, they were denoted with _). Scala bounds work like those from Java: List[? <: Number] is equivalent to List<? extends Number>, while List[? >: Integer] is equivalent to List<? super Integer>. In C++, generic type constraints can be expressed using concepts.

This example is equivalent to the following Java code:

In C#, type bounds can be represented as X<out T> and X<in T> (compared to Java X<? extends T> and X<? super T> respectively) while a generic type constraint is expressed with a where clause. These are more expressive and powerful than Java wildcards.

… excerpt ends here. Continue reading the full article.

Worked examples

Example 1 — a first encounter with Wildcard (Java)

Start with the simplest possible case. Write down what Wildcard (Java) claims or describes in one sentence, then invent the smallest concrete situation in which that sentence is true. In computer science, the smallest case is usually a single object, a single equation or a single measurement. Check that every symbol or term in your sentence has a meaning in that case.

Example 2 — changing one variable

Take the situation from Example 1 and change exactly one quantity: double it, halve it, or set it to zero. Predict what should happen to Wildcard (Java) before you calculate. Comparing your prediction with the result is the fastest way to find out whether you understand the idea or only the words.

Example 3 — an exam-style question

Typical questions about Wildcard (Java) ask you to (a) state it precisely, (b) apply it to given data, and (c) explain a limitation. Practise writing all three answers in under five minutes; the third part is what separates a full-mark answer from an average one.

Applications of Wildcard (Java)

In research
Wildcard (Java) appears in computer science research whenever the underlying quantities have to be modelled precisely. Papers usually cite it as a starting assumption and then explore where it breaks down.
In technology and industry
Engineering practice reuses Wildcard (Java) in design rules, simulations and safety margins. Knowing the idea lets you read a specification sheet and understand why the numbers look the way they do.
In the classroom
Wildcard (Java) is common in secondary-school and first-year university syllabi. It links to neighbouring topics Java (programming language), Polymorphism (computer science), so understanding it makes those chapters shorter.
In everyday life
Look for Wildcard (Java) outside the textbook — in sport, cooking, traffic, electronics or the sky above you. An example you found yourself is remembered far longer than one you were given.
Ask Teacher Smith questions about this articleOpens your AI tutor with a question about “Wildcard (Java)” →

Affiliate

Preply — study more efficiently by working with a personal tutor. 50% off.

How to study Wildcard (Java) in 20 minutes

  1. Read the reference excerpt below once, without taking notes.
  2. Close the page and write down what Wildcard (Java) means in your own words.
  3. Compare your version with the excerpt and mark what you missed.
  4. Work through the three examples above with pen and paper.
  5. Explain Wildcard (Java) out loud to somebody else — or to Teacher Smith in the lgStudy chat.

Frequently asked questions

What is Wildcard (Java) in simple terms?

In the Java programming language, the wildcard ? is a special kind of type argument 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.

Why does Wildcard (Java) matter?

Because it connects several computer science ideas at once: it gives you a definition you can apply, a quantity you can calculate, and a way to check whether a result is plausible.

How should I study Wildcard (Java)?

Read the excerpt, restate it from memory, then work through the examples and applications listed on this page. The five-step study plan above takes about twenty minutes.

What does this page cover?

It gives you a compact reference excerpt plus original lgStudy explanations, examples, applications and study material on Wildcard (Java).

Tags

  • Java (programming language)
  • Polymorphism (computer science)

Keep exploring