当前位置:   article > 正文

Java泛型

Java泛型
一、泛型引入
1、引入:
    1、在使用集合时,不能对加入到集合中的元素类型进行约束,因为集合里面的元素类型为Object。
    2、遍历集合时,需要进行类型转化,如果数据量比较大,那么对效率有影响。
2、说明:
  1. 泛(广泛)型又称参数化类型,是JDK5.0出现的新特性,解决数据类型的安全性问题。
  2. 在类声明或实例化时,只需要指定好需要的具体类型即可。
  3. 可以在类声明时通过一个标识来表示类中某个属性的类型,或者某个方法的返回值类型,或者参数类型。
泛型的声明:
    interface接口<T>{}
    class类<K,V>{}
     <>内的字母没有限制,且实例化时,只能为引用类型,不能是基本数据类型。
    一般:
  • E  - Element (在集合中使用,因为集合中存放的是元素)
  • T  - Type(Java 类)
  • K  - Key(键)
  • V  - Value(值)
  • N  - Number(数值类型)
  •  - 表示不确定的 java 类型
    比如:接口List和类HashMap
        
        
例如:
    Test为一个泛型类,在类声明中出现<E>,在类中就可以使用。
    然后Show()方法为一个泛型方法
    
  •    注意,在定义Test类对象stringTest时制定了E的数据类型,在编译期间,就确定了E的类型。
    
基本原理:
    泛型本质是将数据类型参数化,它通过擦除的方式来实现。
    声明了泛型的 .java 源代码,在编译生成 .class 文件之后,泛型相关的信息就消失了。
    可以认为,源代码中泛型相关的信息,就是提供给编译器用的。泛型信息对 Java 编译器可以见,对 Java 虚拟机不可见。
Java 编译器通过如下方式实现擦除:
    用 Object 或者界定类型替代泛型,产生的字节码中只包含了原始的类,接口和方法;
    在恰当的位置插入强制转换代码来确保类型安全;
    在继承了泛型类或接口的类中插入桥接方法来保留多态性。
3、细节
1.<>内部的T或E等只能是引用类型,不能是基本数据类型。
2.在指定了泛型的具体类型之后,可以传入该类型或该类型的子类类型。
3.泛型使用形式:
    ①正常模式:List<Integer> list = new ArrayListList<Integer>();
    ② 简化模式,实际开发中使用这种:
        编译器会使用类型推断,可以省略后面<>内部的类型。
        List<Integer> list = new ArrayListList<>();
    ③List list = new ArrayList();
        这样写,泛型默认为Object。
二、自定义泛型
1、自定义泛型类
语法:
    class 类名<T、R......>{//可以定义多个
    }
使用细节:
    1.普通成员可以使用泛型(属性、方法)
    2.使用泛型数组,不能初始化。
        因为在new的时候,不知道泛型具体类型,不知道开辟多大的空间。
    3.静态方法中,不能使用类的泛型。
        因为静态方法和类无关,未创建对象(即未指定泛型具体类型)便可以使用。
        所以不指定类型则无法使用,因此静态方法不能使用类的泛型。
    4.泛型类的类型,是在创建对象时确定的(创建对象时,需要指定类型,没有指定则默认为Object)。
2、自定义泛型接口
语法:
    interface 接口名<T、R....>{//可以定义多个
    }
使用细节:
    1.静态成员不能使用泛型。
    2.泛型类型的接口,在继承接口或实现接口时确定,没有指定默认为Object。
3、自定义泛型方法
语法:
    修饰符 <T、R...>返回类型 方法名(参数列表){
    }
细节:
    1.可以定义在普通类中,也可以定义在泛型类中。
    2.方法被调用时,类型就会确定。
    3.public void fun(E e){}
            这是使用了泛型
            不是泛型方法,因为修饰符后面没有泛型列表
三、例子
class A<T,R,M> {
    public <E> void f(E e){//正确,这是泛型类
        System.out.println(e.getClass().getSimpleName());
    }
    public void h(U u){}//错误,U并未定义
    public void M(M m){}//正确,使用了泛型的方法
}
class Dog{}
psvm(){
    A<String,Double,Integer> a = new A<>();
    a.f(10);//自动装箱,输出Integer
    a.f(new Dog);//输出Dog
}
四、泛型的继承和通配
1.泛型不具备继承性
    List<Object> list = new ArrayList<String>();
    //这是错误的,虽然String 时Object的子类,但是不能这样写,但可以直接赋值String。
2.<?>
    支持任意泛型类型
3.<? extends A>
    支持A类以及A类的子类,规定了泛型的上限。
4.<? super A>
    支持A类以及A类的父类,不限于直接父类,规定了泛型的下限。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/659280
推荐阅读
相关标签
  

闽ICP备14008679号