Java SE 中的泛型知道多少呢

本文深入探讨Java泛型的基础概念,包括类型参数、编译时类型擦除、通配符使用等,并介绍了如何利用泛型进行类型安全的编程实践。此外,还解析了协变和逆变的概念及其在Java集合库中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.基础

//类型参数
public class Box<T>{}
public class Box<K,V>{}
//多重参数或接口边界
public class Box<T extends Employee & Printable & Listable>{}

//无界通配符
private List<?> result;
//有界通配符:上边界
private List<? extends Number> result;
//有界通配符:下边界
private List<? super Student> result;

2.编译时类型擦除

interface A{
        int calc(Map<String,List<String>> orders);
        int calc(Map<String,Integer> orders);
}

擦除以后剩下的是原始类型(raw type) Map

3.通配符

例1

//不能编译
List<Object> result=new ArrayList<String>();
//合法
List<?> result=new ArrayList<String>();

例2

//不安全的,计算参数的和
<T> double sum(T ... args){}
//安全的
<T extends Number> double sum(T ... args){}

4.泛型类型

例1

public class Box<T>{
        private T t;
        public void set(T t){
                this.t=t;
        }
        public void test(Box<T> obj){
                //ETC
        }
}

测试

Box<Number> b=new Box<>();
//OK
b.set(new Integer(10));
//不能编译
Box<Integer> a=new Box<>();
b.test(a);

例2

public abstract class BaseEntity<T>{
    //ETC
    private Page<T> page;
    public Page<T> getPage() {
        return page;
    }
    public void setPage(Page<T> page) {
        this.page = page;
    }
}
public class Article extends BaseEntity<Article> {
        //ETC
}
public class Page<T extends BaseEntity<T>> {
    private List<T> result;
}

在开发者工具中会提示BaseEntity.page类型错误,改成

public abstract class BaseEntity<T>{
    private Page<?> page;
    public Page<?> getPage() {
        return page;
    }
    public void setPage(Page<?> page) {
        this.page = page;
    }
}

测试

Article a=new Article();
//Refer也继承了BaseEnity
Page<Refer> rs=new Page<>(1,1);
//绕开了类型检查,但不符合逻辑
a.setPage(rs);

需要修改Page的声明,才可以让原来的开发工具中的警告消失同时类型检查合法并符合逻辑

5.类型变体(协变和逆变:PECS)

String[] strArr={"hello","java","world"}
Object[] objArr=strArr;
//运行时出错
objArr[1]=new Integer(37);
System.out.println(objArr[1]);

java(5以后)集合库大量使用了协变和逆变,使用这种变体的目的是确保泛型作正确的事及表现的行为不会让人感觉怪诞

6.编译时和运行时类型

List<String> str=new ArrayList<>();
System.out.println(str);

javac看到str是 List-of-String
jvm 看到str是ArrayList类型的对象

最后
推荐看一看这几本书.书中对泛型的讲解个人认为都不错,可能初读起来比较绕.抽时间静下来读还是能读懂的

java学习指南(第四版)
java学习指南

java语言导学(第五版)
java语言导学

java技术手册(第六版)
java技术手册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值