【The Java™ Tutorials】【Generics】2. Generic Types

Generic Types

A generic type is a generic class or interface that is parameterized over types.

A Simple Box Class

public class Box {
    private Object object;

    public void set(Object object) { this.object = object; }
    public Object get() { return object; }
}

这种写法的主要问题和上一章举的例子是一样的。

A Generic Version of the Box Class

A generic class is defined with the following format:

class name<T1, T2, ..., Tn> { /* ... */ }
// Tn: type parameters (also called type variables)

下面我们把Box改成generic版本:

/**
 * Generic version of the Box class.
 * @param <T> the type of the value being boxed
 */
public class Box<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

Type Parameter Naming Conventions

  • E - Element (used extensively by the Java Collections Framework)
  • K - Key
  • N - Number
  • T - Type
  • V - Value
  • S,U,V etc. - 2nd, 3rd, 4th types

Invoking and Instantiating a Generic Type

Box<Integer> integerBox = new Box<Integer>();

The Diamond(<>)

从Java 7开始,可以简写成以下形式:

Box<Integer> integerBox = new Box<>();

因为编译器可以推断出integerBox是Box<Integer>类型,具体可以看后面的章节Type Inference。

Multiple Type Parameters

public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}

public class OrderedPair<K, V> implements Pair<K, V> {

    private K key;
    private V value;

    public OrderedPair(K key, V value) {
    this.key = key;
    this.value = value;
    }

    public K getKey()   { return key; }
    public V getValue() { return value; }
}

Parameterized Types

You can also substitute a type parameter (i.e., K or V) with a parameterized type (i.e., List<String>).

OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));

Type Parameter and Type Argument

Type Parameter and Type Argument Terminology: Many developers use the terms "type parameter" and "type argument" interchangeably, but these terms are not the same. When coding, one provides type arguments in order to create a parameterized type. Therefore, the T in Foo<T> is a type parameter and the String in Foo<String> f is a type argument.

Raw Types

A raw type is the name of a generic class or interface without any type arguments.

Box is the raw type of the generic type Box<T>:

Box rawBox = new Box();

为了向后兼容,允许将参数化类型赋给其原始类型:

Box<String> stringBox = new Box<>();
Box rawBox = stringBox;               // OK

但是,如果将原始类型赋给参数化类型,你会收到warning:

Box rawBox = new Box();           // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox;     // warning: unchecked conversion

如果你使用原始类型调用泛型类型中定义的方法,你也会收到warning:

Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8);  // warning: unchecked invocation to set(T)

The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime. Therefore, you should avoid using raw types.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容