Java 定义泛型类、方法和接口

在定义泛型类、方法和接口时,也有一些需要注意的地方,比如:

  • 不能通过类型参数创建对象。
  • 泛型类类型参数不能用于静态变量和方法。
  • 了解多个类型限定的语法。

我们逐个介绍。不能通过类型参数创建对象,比如,T是类型参数,下面的写法都是非法的:

T elm = 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为上界接口。如果有上界类,类应该放在第一个,类型擦除时,会用第一个上界替换。

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!