我是南城余!阿里云开发者平台专家博士证书获得者!
欢迎关注我的博客!一同成长!
一名从事运维开发的worker,记录分享学习。
专注于AI,运维开发,windows Linux 系统领域的分享!
本章节对应知识库泛型 (yuque.com)https://www.yuque.com/nanchengcyu/java/rfng0hcks3gqaork
Java中的泛型,就类似于上述场景中的标签。
》类型不安全。因为add()的参数是Object类型,意味着任何类型的对象都可以添加成功
》需要强转操作,繁琐。还可能导致ClassCastException
自定义泛型类、接口、方法
》class Order
》public
泛型,是程序中出现的不确定的类型
以集合为例,把一个集合中的内容限制在一个特定的数据类型中
泛型使用在
集合:ArrayList、HashMap、Iterator
比较器:Comparable、Comparator
》集合框架在声明接口和其实现类时,使用了泛型(jdk5.0),在实例化集合对象时
如果没有泛型,则认为操作的默认为Object类型的数据
如果使用了泛型,则需要指明泛型的具体操作类型。一旦指明了泛型的具体类型,则在集合的相关方法中,只能添加此类型
//泛型在List中的使用
@Test
public void test1(){
//举例:将学生成绩保存在ArrayList中
//标准写法:
//ArrayList list = new ArrayList();
//jdk7的新特性:类型推断
ArrayList list = new ArrayList<>();
list.add(56); //自动装箱
list.add(76);
list.add(88);
list.add(89);
//当添加非Integer类型数据时,编译不通过
//list.add("Tom");//编译报错
Iterator iterator = list.iterator();
while(iterator.hasNext()){
//不需要强转,直接可以获取添加时的元素的数据类型
Integer score = iterator.next();
System.out.println(score);
}
}
【修饰符】 class 类名<类型变量列表> 【extends 父类】 【implements 接口们】{
}
【修饰符】 interface 接口名<类型变量列表> 【implements 接口们】{
}
//例如:
public class ArrayList
public interface Map{
....
}
[修饰符] <类型变量列表> 返回值类型 方法名([形参列表])[throws 异常列表]{
//...
}
//例如:java.util.Arrays类中的
public static List asList(T... a){
....
}
① 我们在声明完自定义泛型类以后,可以在类的内部(比如:属性、方法、构造器中)使用类的泛型。
② 我们在创建自定义泛型类的对象时,可以指明泛型参数类型。一旦指明,内部凡是使用类的泛型参数的位置,都具体化为指定的类的泛型类型。
③ 如果在创建自定义泛型类的对象时,没有指明泛型参数类型,那么泛型将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。
④ 泛型的指定中必须使用引用数据类型。不能使用基本数据类型,此时只能使用包装类替换。
⑤ 除创建泛型类对象外,子类继承泛型类时、实现类实现泛型接口时,也可以确定泛型结构中的泛型参数。
如果我们在给泛型类提供子类时,子类也不确定泛型的类型,则可以继续使用泛型参数。
我们还可以在现有的父类的泛型参数的基础上,新增泛型参数。
① 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:
② JDK7.0 开始,泛型的简化操作:ArrayList
③ 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
④ 不能使用new E[]。但是可以:E[] elements = (E[])new Object[capacity];
参考:ArrayList源码中声明:Object[] elementData,而非泛型参数类型数组。
⑤ 在类/接口上声明的泛型,在本类或本接口中即代表某种类型,但不可以在静态方法中使用类的泛型。
⑥ 异常类不能是带泛型的。
class Person {
// 使用T类型定义变量
private T info;
// 使用T类型定义一般方法
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
// 使用T类型定义构造器
public Person() {
}
public Person(T info) {
this.info = info;
}
// static的方法中不能声明泛型
//public static void show(T t) {
//
//}
// 不能在try-catch中使用泛型定义
//public void test() {
//try {
//
//} catch (MyException ex) {
//
//}
//}
}
① 类SuperA是类A的父类,则G
比如:ArrayList
② 类SuperA是类A的父类或接口,SuperA
比如:List
即类型必须保持一致
使用说明
》举例:ArrayList>
》G>可以看成G类型的父类,既可以将G的对象赋值给G>类型引用(或变量)
读写数据特点(以集合ArrayList>为例)
》读取数据:允许的,读取的值的类型为Object类型
》写入数据:不允许,特例:但可以写入null值(因为类型未知>)
有限制条件的通配符
List extends A>:可以将List或List赋值给List extends A>,其中B类是A类的子类
List super A>:以将List或List赋值给List super A>,其中B类是A类的父类
有限制条件的通配符的读写条件