java泛型小结

目录

泛型的定义

泛型代码与虚拟机

泛型的限制与局限性

泛型类型的继承规则

通配符

 

 


泛型的定义

1、泛型类就是有一个或多个类型变量的类,泛型方法就是带有类型参数的方法

public class Test<T,E>
{}//类名之后
public static <T> T test()
{}//修饰符之后

2、类型变量的限定

有时类或方法需要对类型变量进行限定,比如这个类型变量需执行compareto()方法,则这个类得继承Comparable接口

public static<T extends Comparable> void test(T t1,T t2)
{
       t1.compareto(t2);
}

泛型代码与虚拟机

1、虚拟机没有泛型类型对象,所有的对象都是普通类。

2、类型擦除,本质上来说,编译器把带有泛型的类源码经过编译,生成相应的原始类型,这个原始类型的名子就是去掉类型参数后的泛型类型名。类型变量被擦除,并替换成限定类型。

 List<String> list=new ArrayList<>();
 List<Integer> list1=new ArrayList<>();
//按照我的理解,这里的两个对象,尽管泛型类型不一样,但是他们都调用的那个擦除后的原始类型。

3、泛型的强转发生在两种情况,其一对方法的调用返回泛型类型的变量,其二当访问一个公共的范型字段时,实际上编译器自动发生了强转

class Pair<T>{
    private T first;
    private T second;

    public T getFirst() {
        return first;
    }

    public void setFirst(T first) {
        this.first = first;
    }

    public T getSecond() {
        return second;
    }

    public void setSecond(T second) {
        this.second = second;
    }
}
Pair<Employee> buddies=...;
Employee buddy=buddies.getFirst();
//这里在编译后的实质得到了Object o,强转成Employee

4、关于编译器生成桥方法

class D extend Pair<String>{
public void setSecond(String second){...}
}

 我们希望用类的多态性,但实际上Pair编译后的方法为:public void setSecond(Object o){...}

产生了冲突,故编译器自动转变为桥方法

class D extend Pair<String>{
public void setSecond(String second){
super.setSecond(second);
}
}//虚拟机的转变

泛型的限制与局限性

1、不能用基本类型实例化类型参数

2、运行时类型查询只适用于原始类型

Pair<String> stringL = new Pair<>();
Pair<Integer>integerL=new Pair<>();
//一个类对应一个Class对象,他们都对应的那个原始类
System.out.println(stringL.getClass()==integerL.getClass());//true

3、不能创建参数化类型的数组,由于擦除,数组没有了类型限制,会发生错误

Pair[] pairs=new Pair<String>[10];//此种写法错误
Pair<String>[] pairs=new Pair[3];//如此写符合语法

4、不能实例化类型变量,new T()等效于new Object()没意义

5、不能有return  (T[])new Object[2]; 这里的前置只是样子货,语法上Object[]可以强转为T[],但实质仍为Object[],运行起来会抛出异常;

但由于原类限定型 return (T[])new Comparable[2] ;会抛出异常。

子类的对象可以赋值给父类的引用,父类的对象可以强转为子类的引用,但要强转不抛出异常,需要父类引用指向的本身为子类对象。

6、泛型类的静态上下文中的类型变量无效,静态方法中不能引用类型变量。

泛型类型的继承规则

1、ArrayList<String>,ArrayList<Integer>与ArrayList<Object>没有任何关系,Arraylist是他们的父类

2、ArrayList<String>,ArrayList<Integer>与ArrayList<Object>的父类是List<String>,List<Integer>与List<Object>;List<String>,List<Integer>与List<Object>的父类也是List;ArrayList的父类是List;

 3、若A是B的子类,A[]是B[]的子类,则B[] b=new A[2],合法。

通配符

1、通配符有三种表现形式:

 ArrayList<? extends Comparable> arrayList=new ArrayList<Integer>();
 ArrayList<? super String> arrayList1=new ArrayList<String>();
 ArrayList<? > arrayList2=new ArrayList<Object>();

通配符用的地方在泛型类定义好之后,写入那个未知的类型变量E。

2、 ArrayList<? extends Comparable>可以被ArrayList<所有实现Comparable接口的类>赋值

     ArrayList<? super String>可以被ArrayList<String或String的超类>赋值

   ArrayList<? > 可以被ArrayList<任意类包括Object>赋值

ArrayList<Object>与ArrayList<Integer>没有任何关系,ArrayList<? >的父类是ArrayList

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值