欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 泛型(遇到一些问题未解决)

程序员文章站 2024-03-14 18:41:22
...

1.泛型

泛型是 JDK 1.5 之后才有的,可以在编译时期(泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息进行类型检查,且可以避免频繁类型转化。

2.泛型关键字

extends (上限)

在创建泛型方法的时候使用, 可以限定传入参数类型

    // 传入的参数必须要同时实现Comparable 和 Serializable 接口(即T为它们的子类),多个限定之间用&连接
    public static <T extends Comparable & Serializable> void test(T o1, T o2) {

    }

    public static void main(String[] args) {
        test("123", "1234");
    }

传入的参数为集合时,可以限定集合中的元素类型

// 传入的集合里面的元素必须要为Number的子类,否则报错
public void save(List<? extends Number> list) {
}

super (下限)

super用法与extends大致一样

? extends 限定元素 , 即 ? 要继承自限定元素, ? 为限定元素的子类

? super    限定元素 , 即限定元素要继承 ? , ? 为限定元素父类

3.类型擦除

无论何时定义一个泛型, 都自动提供了一个相应的原始类型, 原始类型即为泛型类型擦除类型变量, 并替换为限定类型(有多个限定类型就用第一个限定类型, 无限定类型就用Object替换)的结果.

例如定义一个泛型类Pair

class Pair<T extends Comparable & Serializable> {
    private T first;
    private T second;

    public Pair(T first, T second) {
        this.first = first;
        this.second = 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;
    }
}

这个类的原始类型为

class Pair<T extends Comparable & Serializable> {
    private Comparable first;
    private Comparable second;

    public Pair(Comparable first, Comparable second) {
        this.first = first;
        this.second = second;
    }

    public Comparable getFirst() {
        return first;
    }

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

    public Comparable getSecond() {
        return second;
    }

    public void setSecond(Comparable second) {
        this.second = second;
    }
}
public void save(List<String> p){
}
public void save(List<Integer> d){    // 报错: 与上面方法编译后一样
}

在使用泛型类时, 在适当的时候编译器会自动插入强制转换

Pair<String> pair = new Pair<String>("123", "1234");
pair.getFirst(); // 编译器会自动将得到的结果强制转换为String类型

桥方法

(遇到一个问题不知道什么原因, 继承泛型类后, 子类中的方法名与父类中相同,参数不同也会覆盖父类方法)

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

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

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

    public T getSecond() {
        return second;
    }

    public void setSecond(T second) {
        System.out.println("Pair.setSecond()");
        this.second = second;
    }

    @Override
    public String toString() {
        return "[ " + first.toString() + " , " + second.toString() + " ]";
    }
}

class StringInterval extends Pair<String> {
    public StringInterval(String first, String second) {
        super(first, second);
    }

    public void setSecond(String date) {
        System.out.println("DataInterval.setSecond(String date)");
        super.setSecond(date);
    }
}
        StringInterval interval=new StringInterval("123", "1234");
        Pair<String> pair=interval;
        interval.setSecond("4567");
        System.out.println(interval);
        System.out.println(pair);
        System.out.println("------------------");
        pair.setSecond("78910");
        System.out.println(interval);
        System.out.println(pair);
结果--------------------------------------------------------------------------------------
DataInterval.setSecond(String date)
Pair.setSecond()
[ 123 , 4567 ]
[ 123 , 4567 ]
------------------
DataInterval.setSecond(String date)
Pair.setSecond()
[ 123 , 78910 ]
[ 123 , 78910 ]