泛型

1、      泛型

泛型本质是指类型参数化。

允许在定义类、接口、方法时使用类型形参,当时用时指定具体类型。

所有使用该泛型参数的地方都被统一化,保证类型一致。如果未指定类型,默认是object类型。集合体系中所有的类型增加了泛型,泛型主要用于集合。

2、      泛型的优势

1)      不需要强转

2)      更安全

3)      可见性好

3、      使用

 

 

1)      泛型类(用在类的上面)

static class ObjectTool<T> {
    private T obj;
    public T getObj() {
        return obj;
    }
    public void setObj(T obj) {
        this.obj = obj;
    }
}

2)      泛型方法(用在方法上面)

public class MethodGenericity<T> {
    public static void main(String[] args) {
        //创建对象
       
ObjectTool tool = new ObjectTool();
        //调用方法,传入的参数是什么类型,返回值就是什么类型
       
tool.show("hello");
        tool.show(12);
        tool.show(12.5);
    }

    static class ObjectTool {
        //定义泛型方法..
       
public <T> void show(T t) {
            System.out.println(t);
        }
    }
}

3)      泛型类派生的子类

/**
 * 把泛型定义在接口上
 */
interface Inter<T> {
    void show(T t);
}

/**
 * 子类明确泛型类的类型参数变量
 */
class InterImpl1 implements Inter<String> {
    @Override
    public void show(String s) {
        System.out.println(s);
    }
}

/**
 * 子类不明确泛型类的类型参数变量,实现类也要定义出T的类型
 */
class InterImpl2<T> implements Inter<T> {
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

1、      泛型通配符

public void test3(List<?> list) {
    for (int i = 0; i < list.size(); i++) {
        // list.add(list.get(0)); // 编译错误
       
System.out.println(list.get(i));
    }
}
 
public <T> void test4(List<T> list) {
    for (int i = 0; i < list.size(); i++) {
        // list.add(list.get(0)); // 编译阶段ok,但是运行时抛异常,Exception in thread "main" java.lang
        // .UnsupportedOperationException
       
System.out.println(list.get(i));
    }
}

2、      泛型的上限和下限

泛型的上限:

格式:类型名称<? Extends 类> 对象名称

意义:只能接受该类型及其子类

泛型的下限:

格式:类型名称<? super 类> 对象名称

意义:只能接受该类型及其父类

   PECS法则

   总结 ? extends 和 ? super 通配符的特征,我们可以得出以下结论:

  • 如果你想从一个数据类型里获取数据,使用 ? extends 通配符
  • 如果你想把对象写入一个数据结构里,使用 ? super 通配符

3、      类型擦除和桥接方法

  • 泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛型信息,以此使程序运行效率不受到影响,这个过程称之为 “擦除”
  • 由于类型被擦除了,为了维持多态性,所以编译器就自动生成了桥接方法
/**
 * 桥接方法
 * 1> 类型擦除 javac ——> class 泛型被擦除了!
 * 2> 泛型虽然被擦除了,但是,你一定要给我保留泛型的行为!
 * @param <>
 */

 

posted @ 2021-02-15 10:00  majingyun  阅读(52)  评论(0)    收藏  举报