Java教程
  • Introduction
  • Getting Started
    • The Java Technology Phenomenon
      • About the Java Technology
      • What Can Java Technology Do?
      • How Will Java Technology Change My Life?
    • The Hello World Application
    • A Closer Look at the Hello World Application
  • Learning the Java Language
    • Object-Oriented Programming Concepts
      • What Is an Object?
      • What Is a Class?
      • What Is Inheritance?
      • What Is an Interface?
      • What Is a package?
    • Language Basics
      • Java Language Keywords
    • Annotations
      • Annotations Basics
      • Declaring an Annotation Type
      • Predefined Annotation Types
      • Repeating Annotations
      • Type Annotations and Pluggable Type Systems
    • Generics
      • 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
Powered by GitBook
On this page

Was this helpful?

  1. Learning the Java Language
  2. Generics
  3. Wildcards

Wildcards and Subtyping

PreviousLower Bounded WildcardsNextWildcard Capture and Helper Methods

Last updated 5 years ago

Was this helpful?

在已经讨论过,泛型类或者接口之所以是不相关仅因为它们的类型之间存在关系。然而,你可以用通配符去创建泛型类或者接口之间的关系。

以下面两个常规(非泛型)类为例:

class A { /* ... */ }
class B extends A { /* ... */ }

下面的代码也是合理的:

B b = new B();
A a = b;

上面上代码显示了常规类的继承遵循了子类型规则:如果B扩展自A,则类B是类A的子类型。该规则不适用于泛型类型:

List<B> lb = new ArrayList<>();
List<A> la = lb;   // compile-time error

既然Integer是Number的子类型,那么List <Integer>和List <Number>之间的关系是什么呢?

The common parent is List<?>.

虽然Integer是Number的子类型,但是List<Integer>不是List<Number>的子类型,实际上,这两个类型并没有关联。List<Number>和List<Integer>的共同父类是List<?>

为了在这些类之间创建关系,以便代码可以通过List <Integer>的元素访问Number的方法,请使用上界通配符:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

因为Integer是Number的子类型,并且numList是Number对象的列表,所以现在intList(Integer对象的列表)和numList之间存在关系。下图展示了了使用上下界通配符声明的几个List类之间的关系。

A hierarchy of several generic List class declarations.

部分提供有更多关使用上界和下界通配符的后果的信息

Guidelines for Wildcard Use
Generics, Inheritance, and Subtypes