Java初探-11.Java中泛型类,方法和接口的定义

82 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

Java 中在定义泛型类、方法和接口时,有几个注意点:

  • 不能用类型参数来创建对象;
  • 泛型类型参数不能用于静态变量和方法;
  • 多个类型限定的表示。

以下举例说明下:

  • 不能通过类型参数创建对象,比如T是类型参数,下面的写法是错误的:
T e = new T();
T[] arr = new T[10];

为什么错误呢?如果允许,那么用户会以为创建的就是对应类型的对象,但由于类型擦除的原因,Java创建Object类型的对象,而无法创建T类型的对象,容易引起误解,Java干脆禁止这样。

如果希望根据类型创建对象呢?需要设计API接受类型对象,即Class对象,并使用Java中反射机制。如果类型有默认构造函数,可调用Class的newInstance方法构建对象,类似下面这样:

public static <T> T create(Class<T> type){
    try {
        return type.newInstance();
    } catch (Exception e) {
        return null;
    }
}

如:

Date date = create(Date.class);
StringBuilder sb = create(StringBuilder.class);

对于泛型类声明的类型参数,可以在实例变量和方法中使用,但在静态变量和静态方法中是不能使用的。下面这种写法是非法的:

public class Singleton<T> {
    private static T instance;
    public synchronized static T getInstance(){
        if(instance==null){
              //创建实例
        }
        return instance;
    }
}

由于类型擦除,Singleton类型只有一份,静态变量和方法都是类型的属性,且与类型参数无关,所以不能使用泛型类类型参数。 对于静态方法,可以是泛型方法,可以声明自己的类型参数,因为这个参数与泛型类的类型参数是没有关系的。

Java中还支持多个上界,多个上界之间以&分隔,类似这样:

T extends Base & Comparable & Serializable

Base为上界类,Comparable和Serializable为上界接口。如果有上界类,类应该放在第一个,类型擦除时,会用第一个上界替换。