0
点赞
收藏
分享

微信扫一扫

iOS组件化 方案 实现

c一段旅程c 2024-05-31 阅读 9
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 或者界定类型替代泛型,产生的字节码中只包含了原始的类,接口和方法;

    在恰当的位置插入强制转换代码来确保类型安全;

    在继承了泛型类或接口的类中插入桥接方法来保留多态性。

详情: Java 中泛型的实现原理 - 博客园

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类的父类,不限于直接父类,规定了泛型的下限。

举报

相关推荐

0 条评论