Documentation
The Java™ Tutorials
Download Ebooks
Download JDK
Search Java Tutorials
Hide TOC
Generics (Updated)
Why Use Generics?
Generic Types
Raw Types
Generic Methods
Bounded Type Parameters
Generic Methods and Bounded Type Parameters
Generics, Inheritance, and Subtypes
Type Inference
Wildcards
Upper Bounded Wildcards
Unbounded Wildcards
Lower Bounded Wildcards
Wildcards and Subtyping
Wildcard Capture and Helper Methods
Guidelines for Wildcard Use
Type Erasure
Erasure of Generic Types
Erasure of Generic Methods
Effects of Type Erasure and Bridge Methods
Non-Reifiable Types
Restrictions on Generics
Questions and Exercises
Trail: Learning the Java Language
Lesson: Generics (Updated)
Section: Wildcards
« Previous • Trail • Next »

# Guidelines for Wildcard Use

One of the more confusing aspects when learning to program with generics is determining when to use an upper bounded wildcard and when to use a lower bounded wildcard. This page provides some guidelines to follow when designing your code.

For purposes of this discussion, it is helpful to think of variables as providing one of two functions:

An "In" Variable
  An "in" variable serves up data to the code. Imagine a copy method with two arguments: `copy(src, dest)`. The `src` argument provides the data to be copied, so it is the "in" parameter.
An "Out" Variable
  An "out" variable holds data for use elsewhere. In the copy example, `copy(src, dest)`, the `dest` argument accepts data, so it is the "out" parameter.

Of course, some variables are used both for "in" and "out" purposes — this scenario is also addressed in the guidelines.

You can use the "in" and "out" principle when deciding whether to use a wildcard and what type of wildcard is appropriate. The following list provides the guidelines to follow:

Wildcard Guidelines:

- An "in" variable is defined with an upper bounded wildcard, using the `extends` keyword.
- An "out" variable is defined with a lower bounded wildcard, using the `super` keyword.
- In the case where the "in" variable can be accessed using methods defined in the `Object` class, use an unbounded wildcard.
- In the case where the code needs to access the variable as both an "in" and an "out" variable, do not use a wildcard.

These guidelines do not apply to a method's return type. Using a wildcard as a return type should be avoided because it forces programmers using the code to deal with wildcards.

A list defined by `List<? extends ...>` can be informally thought of as read-only, but that is not a strict guarantee. Suppose you have the following two classes:

    class NaturalNumber {

        private int i;

        public NaturalNumber(int i) { this.i = i; }
        // ...
    }

    class EvenNumber extends NaturalNumber {

        public EvenNumber(int i) { super(i); }
        // ...
    }

Consider the following code:

    List<EvenNumber> le = new ArrayList<>();
    List<? extends NaturalNumber> ln = le;
    ln.add(new NaturalNumber(35));  // compile-time error

Because `List<EvenNumber>` is a subtype of `List<? extends NaturalNumber>`, you can assign `le` to `ln`. But you cannot use `ln` to add a natural number to a list of even numbers. The following operations on the list are possible:

- You can add `null`.
- You can invoke `clear`.
- You can get the iterator and invoke `remove`.
- You can capture the wildcard and write elements that you've read from the list.

You can see that the list defined by `List<? extends NaturalNumber>` is not read-only in the strictest sense of the word, but you might think of it that way because you cannot store a new element or change an existing element in the list.

« Previous • Trail • Next »

Previous page: Wildcard Capture and Helper Methods
Next page: Type Erasure