java核心技术(高阶)之二 泛型(上)

1.泛型简介

泛型:编写的代码可以被很多不同类型的对象所重用(ArrayList<String>,ArrayList<Integer>,ArrayList<Double>)
泛型的本质:参数化类型,避免类型转换,代码可复用
泛型类:ArrayList,HashSet,HashMap等
泛型方法:Collections.binarySearch,Arrays.sort等
泛型接口:LIst,Iterator等

2.泛型设计

1.泛型类:具有泛型变量的类,在类名后用代表引入类型(或<T,u>)

关于其中的大写字母,一般情况如下:
ArrayList<E>,E表示单个元素Elements
<K,V>

2.泛型类调用


public class generic{

    public static void main(String[] args){
        Interval<Integer> v1 = new Interval<>(1,2);
        Interval<Integer> v2 = new Interval<>(3,4);
        System.out.println(v1.getLower());
        System.out.println(v2.getUpper());

        Interval<Integer> v3 = reverse(v2);
        System.out.println(v3.getLower()+","+v3.getUpper());
    }

   //注意加上<T>!!!!!!!!!!!在泛型类中的泛型方法,详情见下
    public static <T> Interval<T> reverse(Interval<T> interval){
        return new Interval<T>(interval.getUpper(),interval.getLower());
    }
}

class Interval<T>{
    T lower;
    T upper;

    public Interval(T lower,T upper){
        this.lower = lower;
        this.upper = upper;
    }

    public T getLower(){
        return this.lower;
    }

    public T getUpper(){
        return this.upper;
    }
}

2.泛型方法:具有泛型参数的方法,该方法可在普通类/泛型类中,在泛型类中在修饰符后返回类型前。

public class ArrayUtil{
    public static <T> T getMiddle(T... a){
        return a[a.length/2];
    }
}

String s1 = ArrayUtil.<String>getMiddle("df","as","dd");
Integer i = ArrayUtil.getMiddle(1,2,3);

3.泛型接口
在类名后加,实现接口时指定类型

/*泛型接口*/
interface caculator<T>{
    public T add(T oper1,T oper2);        
}

public class generic_interface implements caculator<Integer>{
    public Integer add(Integer oper1,Integer oper2){
        return oper1 + oper2;
    }

    public static void main(String[] args){
        generic_interface obj = new generic_interface();
        int a = obj.add(1,2);

        caculator<Integer> obj2 = new generic_interface();
        int b = obj2.add(3,4);

        System.out.println(a + "," + b);

    }

}
T也可以再是一个泛型类
public class IntervalCalculator implements Calculator<Interval<Integer>>{
    public static void main(String[] args){
        Calculator<Inrerval<Integer>> c = new IntervalCalculator();
        Interval<Integer> oper1 = new Interval<>(1,2);
        Interval<Integer> oper1 = new Interval<>(3,4);
        Interval<Integer> result = c.add(oper1,oper2);
        System.out.println("["+result.getLower()+","+result.getUpper()+"]");
    }
//不用加Integer因为是在普通类中的泛型方法
    public Interval<Integer> add(Interval<Integer oper1,Interval<Integer> oper2){
        int lower = oper1.getLower() + oper2.getLower():
        int upper = oper1.getUpper() + oper2.getUpper();
        return new Interval<Integer>(lower,upper);
}

3.泛型类型限定

1. 如<T extends Comparable>约定T必须是Comparable的子类
2. extends固定,后面可以多个,以&拼接。
3. extends限定可以有多个接口,但只能一个类,且类必须排在第一位,逗号隔参数,<T extends File&Cloneable,U extends Serializable>
泛型类之间的继承:
Pair<S>和Pair<T>没有任何关系,无论S和T之间是什么关系
1. 通配符:
上限界定符:Pair<? entends S>,能接受S自身或子类,只能get,不能set
下线界定符:Pair<? super S>,能接受S自身或超类,只能set,不能get(不能调用方法)
2. 通配符符合PECS原则(Producer extends ,Consumer super):
Pair<? entends S>生产者,只能get,不能set,即只能生产,不能消费
Pair<? super S>消费者,只能set,不能get,即只能消费,不能生产
3. 无限定通配符
   Pair<?>表示任意类型,get只能赋值给Object,set不能放入任何对象

4.泛型实现的本质和约束

为了向后兼容,JVM中实际上没有泛型对象,而是采用类型擦除技术,只有普通的类和方法

5.Java类型变化关系

定义:更复杂类型中的子类型关系,与子类型之间的关系相关联。
若A,B是类型,f(~)表示类型转换,<= 表示继承关系(左边继承于右边)

  1. f(~)是协变的,如果A<=B,有f(A)<=f(B)
  2. f(~)是逆变的,如果A<=B,有f(B)<=f(A)
  3. f(~)是不变的,当上述两种都不成立,即F(A)和F(B)没有关系
  4. f(~)是双变的,如果f(B)<=f(A),有f(A)<=f(B)和2同时成立

Java数组是协变的,不采用通配符的泛型是不变的
采用上限通配符的泛型是协变的,采用下限通配符的泛型是逆变的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值