- 编译时不检查类型的异常
- 集合不能保证集合中的类型一致,运行会报异常,所以引入了泛型
- 使用泛型
- 定义:
- 参数化类型,被成为泛型,允许程序在创建集合时指定集合元素的类型
- 示例:Java7以前List<String> str = new ArrayList<String>;
- 定义:
- Java9增强的“菱形”语法
- 示例:Java7以后List<String> str = new ArrayList<>;
- 菱形语法对原有的泛型并没有改变,只有更好地简化了泛型编程
- 注意:如果使用var声明变量,则无法使用菱形语法
- 示例:Java7以后List<String> str = new ArrayList<>;
- 泛型深入
- 定义泛型接口、类
- 当创建泛型声明的自定义类,为该类定义构造器时,构造器名还是原来的类名,不要增加泛型声明,例如为Apple<T>类定义构造器,某构造器名依然是Apple,而不是Apple<T>,调用该构造器时却可以使用Apple<T>的形式,当然应该为T形参传入实际的类型参数,Java7提供了“菱形”语法,允许省略<>中的类型实参。
- 从泛型类派生子类
- 当创建带泛型声明的接口、父类之后,可以为该接口创建实现类,或从该父类派生子类,需要指出的是,当使用这些接口、父类时不能再包含泛型类型。
- 如果从Apple<String>类派生子类,则在Apple类中所有使用T类型的地方都将被替换成String类型,即它的子类将会继承到String getInfo()和void setInfo(String info) 两个方法,如果子类需要重写父类的方法,就必须注意这一点。
- 并不存在泛型类
- 前面提到,可以把ArrayList<String>类当成ArrayList的子类,事实上,ArrayList<String>类也确实像一种特殊的ArrayList类;该ArrayList<String>对象只能添加String对象作为集合元素。但实际上,系统并没有为ArrayList<String>生成新的class文件,而且也不会把ArrayList<String>当成新类来处理。
- 不管为泛型传入哪一种类型的实参,对于Java来说,它们依然被当成同一类来处理,在内存中也只占用一块内存空间,因此在静态方法、静态初始化块或者静态变量(他们都是类相关的)的声明和初始化中不允许使用泛型形参。
- 定义泛型接口、类
- 类型通配符
- 没有类型通配符的情况:
- List<String>对象不能被当成List<Object>对象使用,也就是说,List<String>类并不是List<Object>类的子类。
- *如果Foo是Bar的一个子类型(子类或子接口),而G是具有泛型声明的类或接口,G<Foo>并不是G<Bar>的子类型.
- 在Java早期的设计中,允许Integer[]变量赋值给Number[]变量存在缺陷,因此在Java泛型设计时,进行了改进,它不再允许把List<Integer>对象赋值给List<Number>变量。
- Java泛型设计的原则是,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException异常。
- 数组和泛型有所不同,假设Foo是Bar的一个子类型(子类或者接口),那么Foo[]依然是Bar[]的子类型;但G<Foo>不是G<Bar>的子类型。Foo[]自动向上转型为Bar[]的方式被称为型变,也就是说,Java的数组支持型变,但Java集合并不支持型变。
- 使用类型通配符
- 目的:
- 为了表示各种集合的父类,可以使用类型通配符,类型通配符是一个问号(?),将一个问号作为类型实参传给List集合,写作List<?>(意思是元素类型未知的List)。这个问号(?)被称为通配符,它的元素类型可以匹配任何类型。
- 但这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素加入到其中,唯一的例外是null,他是所有引用类型的子类。
- 目的:
- 设定类型通配符的上限
- 问号一定是后面的类的子类型(也可以是类本身),因此可以把后面的类称为这个通配符(也就是问号)的上限
- 设定类型通配符的下限
- 设定泛型形参的上限
- Java泛型不仅允许在使用通配符时设定上限,而且可以在定义泛型形参时设定上限,用于表示传给该泛型形参的实际类型要么是该上限类型,要么是该上限类型的子类。
- 没有类型通配符的情况:
- 泛型方法
- 概念:
- 在定义类、接口时可以使用泛型形参,在该类的方法定义和成员变量定义、接口的方法定义中,这些泛型形参可被当成普通类型来用,在另外一种情况下,定义类、接口时没有使用感性形参,但定义方法时想自己定义泛型形参,这也是可以的。
- 定义泛型方法
- 为什么有泛型方法的存在:
- P360页,一个方法可以供多个不同类型的方法使用,扩展性很强。
- 为什么有泛型方法的存在:
- 概念:
- 擦除和转换
- 泛型与数组
- 泛型入门
- 编译时不检查类型的异常
- 集合不能保证集合中的类型一致,运行会报异常,所以引入了泛型
- 使用泛型
- 定义:
- 参数化类型,被成为泛型,允许程序在创建集合时指定集合元素的类型
- 示例:Java7以前List<String> str = new ArrayList<String>;
- 定义:
- Java9增强的“菱形”语法
- 示例:Java7以后List<String> str = new ArrayList<>;
- 菱形语法对原有的泛型并没有改变,只有更好地简化了泛型编程
- 注意:如果使用var声明变量,则无法使用菱形语法
- 示例:Java7以后List<String> str = new ArrayList<>;
- 编译时不检查类型的异常
【java基础】泛型
最新推荐文章于 2024-07-30 20:50:32 发布