学习笔记 | 泛型

本贴最后更新于 1960 天前,其中的信息可能已经时异事殊

泛型

泛型适用的是类型,而不能是简单类型
泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。
List<Integer>List<Boolean> 的 Class 是一样的,所以说类型相同
泛型标识 <泛型标识> 可以声明在类和方法
? 代表的某一种类型,而不是多种,是实际的参数,而不是像 T 的形式参数

泛型的使用

泛型类

public class GenericsClass<T> {
    private T key;
    public GenericsClass(T key)
    {
        this.key = key;
    }
    public T getKey() {
        return key;
    }
}

表明 T 是泛型类型

使用

GenericsClass<Integer> a = new GenericsClass<Integer>(123); //显示声明
GenericsClass a = new GenericsClass(123);

GenericsClass<?> 可以匹配任何类型,但是只能使用 Object 的方法

泛型接口

public interface GenericsInterface<T> {   
    public T hello();   
}  

实现接口

可以还是返回泛型

public class GenericsImpl<Anything> implements GenericsInterface {

    @Override

    public Anything hello() {

        return null;

    }

}

或者返回具体类

public class GenericsImpl implements GenericsInterface<Object> {

    @Override

    public Object hello() {

        return null;

    }

}

泛型方法

public class GenericsMethod<T> {
private T key;

    public T hello()

    {
        return key;
    }
    public <T> T hello(GenericsClass<T> genericsClass)
    {
        T a = genericsClass.getKey();
        return a;
    }
}

只要方法有 <泛型标识>,那么即使方法中声明的泛型 T 与类声明的泛型 T 是一个字母,但是他们是两个不同的泛型,所以说泛型方法能使方法独立于类而产生变化
类中定义使用泛型的静态方法,需要添加额外的泛型声明

public static <T> void show(T t){}

无论何时,如果你能做到,你就该尽量使用泛型方法。也就是说,如果使用泛型方法将整个类泛型化,

那么就应该使用泛型方法。另外对于一个 static 的方法而已,无法访问泛型类型的参数。

所以如果 static 方法要使用泛型能力,就必须使其成为泛型方法。

泛型的上下边界

GenericsClass<T extends Number>

表示 GenericsClass 可以声明为 GenericsClass<Number 及其子类 >

GenericsClass<T super Number>

表示 GenericsClass 可以声明为 GenericsClass<Number 及其父类 >

集合与泛型

List
普通的集合定义,可以存放任何数据

List<Object>
泛型限制 Object,但是 List却不能赋值给 List,可以赋值给 List<?>

List<?>
泛型通配符,可以删除,赋值但是不能添加,
因为?代表着某一类型,而这个类型我们是未知的,所以我们添加不了

List<? extends T>
泛型通配符,可以删除,赋值 T 以及 T 的子类 List,但是不能添加,Get 可以返回 T 以及 T 的父类的对象
不管赋值什么,这个 List 都是 T 的子类,所以 get 的时候不管 List 引用了什么,都能向上转型为 T
List<? super T>
泛型通配符,可以删除,赋值 T 以及 T 的父类 List,添加 T 以及 T 的子类,Get 可以返回 Object 对象
因为 ? 一定是 T 或者 T 的父类,所以我们只要添加 T 或者 T 的子类的对象,这些对象都能向上转型为 T 或者 T 的父类,返回的就是 T 或者 T 的父类

我的疑问与解答

有个 List<Object> 里有个 String 类型,List 可以赋值给 List<? super Number>

因为 Object 是 Number 的父类, 而 String 类型 被看成了 Object 对象

List<Object> a1 = new ArrayList();
a1.add("String");
List<? super Number> c = a1;
System.out.println(c.get(0).getClass()); 

List<Object> a1 = new ArrayList();
a1.add("String");
List<? super Number> c = a1;
System.out.println(c.get(0).getClass());` 

还是得到了 class java.lang.String -.-

但是实际上 String 类型即使被当做 Object 类型,它还是 String 类型,只是不能转换为 Number 类型而已,所以 getclass 出来的还是 java.lang.string 🐙

  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...