Java泛型

简介: Java泛型

我是南城余!阿里云开发者平台专家博士证书获得者!

欢迎关注我的博客!一同成长!

一名从事运维开发的worker,记录分享学习。

专注于AI,运维开发,windows Linux 系统领域的分享!


 

Java中的泛型,就类似于上述场景中的标签。

泛型

在集合中使用泛型之前可能存在的问题

》类型不安全。因为add()的参数是Object类型,意味着任何类型的对象都可以添加成功

》需要强转操作,繁琐。还可能导致ClassCastException

自定义泛型类、接口、方法

class Order<T>{}

》public <E>返回值类型 方法名(形参列表){}(<E>在返回值类型前面才能判断其为泛型)

泛型,是程序中出现的不确定的类型

以集合为例,把一个集合中的内容限制在一个特定的数据类型中

使用说明

泛型使用在

集合:ArrayList、HashMap、Iterator

比较器:Comparable、Comparator

》集合框架在声明接口和其实现类时,使用了泛型(jdk5.0),在实例化集合对象时

如果没有泛型,则认为操作的默认为Object类型的数据

如果使用了泛型,则需要指明泛型的具体操作类型。一旦指明了泛型的具体类型,则在集合的相关方法中,只能添加此类型

//泛型在List中的使用
@Test
public void test1(){
    //举例:将学生成绩保存在ArrayList中
    //标准写法:
    //ArrayList<Integer> list = new ArrayList<Integer>();
    //jdk7的新特性:类型推断
    ArrayList<Integer> list = new ArrayList<>();
    list.add(56); //自动装箱
    list.add(76);
    list.add(88);
    list.add(89);
    //当添加非Integer类型数据时,编译不通过
    //list.add("Tom");//编译报错
    Iterator<Integer> iterator = list.iterator();
    while(iterator.hasNext()){
        //不需要强转,直接可以获取添加时的元素的数据类型
        Integer score = iterator.next();
        System.out.println(score);
    }
}
在哪里可以声明类型变量<T>
  • 声明类或接口时,在类名或接口名后面声明泛型类型,我们把这样的类或接口称为泛型类或泛型接口。
【修饰符】 class 类名<类型变量列表> 【extends 父类】 【implements 接口们】{
}
【修饰符】 interface 接口名<类型变量列表> 【implements 接口们】{
}
//例如:
public class ArrayList<E>    
public interface Map<K,V>{
    ....
}
  • 声明方法时,在【修饰符】与返回值类型之间声明类型变量,我们把声明了类型变量的方法,称为泛型方法。
[修饰符] <类型变量列表> 返回值类型 方法名([形参列表])[throws 异常列表]{
    //...
}
//例如:java.util.Arrays类中的
public static <T> List<T> asList(T... a){
    ....
}
说明

① 我们在声明完自定义泛型类以后,可以在类的内部(比如:属性、方法、构造器中)使用类的泛型。

② 我们在创建自定义泛型类的对象时,可以指明泛型参数类型。一旦指明,内部凡是使用类的泛型参数的位置,都具体化为指定的类的泛型类型。

③ 如果在创建自定义泛型类的对象时,没有指明泛型参数类型,那么泛型将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。

  • 经验:泛型要使用一路都用。要不用,一路都不要用。

④ 泛型的指定中必须使用引用数据类型。不能使用基本数据类型,此时只能使用包装类替换。

⑤ 除创建泛型类对象外,子类继承泛型类时、实现类实现泛型接口时,也可以确定泛型结构中的泛型参数。

如果我们在给泛型类提供子类时,子类也不确定泛型的类型,则可以继续使用泛型参数。

我们还可以在现有的父类的泛型参数的基础上,新增泛型参数。

注意

① 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>

② JDK7.0 开始,泛型的简化操作:ArrayList<Fruit> flist = new ArrayList<>();

③ 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。

④ 不能使用new E[]。但是可以:E[] elements = (E[])new Object[capacity];

参考:ArrayList源码中声明:Object[] elementData,而非泛型参数类型数组。

⑤ 在类/接口上声明的泛型,在本类或本接口中即代表某种类型,但不可以在静态方法中使用类的泛型。

⑥ 异常类不能是带泛型的。

class Person<T> {
    // 使用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<T> ex) {
        //
        //}
    //}
}
泛型在继承上的体现

① 类SuperA是类A的父类,则G<SuperA>与G<A>的关系,G<SuperA>和G<A>是并列的两个类,没有任何子类关系

比如:ArrayList<Object>、ArraryList<String>没有关系

② 类SuperA是类A的父类或接口,SuperA<G>与A<G>的关系:SuperA<G>与A<G>有继承或实现关系

比如:List<String>与ArrayList<String>

类型必须保持一致

通配符 :?

使用说明

》举例:ArrayList<?>

》G<?>可以看成G<A>类型的父类,既可以将G<A>的对象赋值给G<?>类型引用(或变量)

读写数据特点(以集合ArrayList<?>为例)

》读取数据:允许的,读取的值的类型为Object类型

》写入数据:不允许,特例:但可以写入null值(因为类型未知<?>)

有限制条件的通配符

List<? extends A>:可以将List<A>或List<B>赋值给List<? extends A>,其中B类是A类的子类

List<? super A>:以将List<A>或List<B>赋值给List<? super A>,其中B类是A类的父类

有限制条件的通配符的读写条件

目录
相关文章
|
6天前
|
存储 Java 编译器
深入理解 Java 泛型和类型擦除
【4月更文挑战第19天】Java泛型是参数化类型,增强安全性与可读性,但存在类型擦除机制。类型擦除保证与旧版本兼容,优化性能,但也导致运行时无法访问泛型信息、类型匹配问题及数组创建限制。为应对这些问题,可使用Object类、instanceof运算符,或借助Guava库的TypeToken获取运行时类型信息。
|
6天前
|
JavaScript Java 编译器
Java包装类和泛型的知识点详解
Java包装类和泛型的知识点的深度理解
|
6天前
|
Java
java中的泛型类型擦除
java中的泛型类型擦除
14 2
|
6天前
|
安全 Java 程序员
Java 泛型
Java 泛型
16 0
|
1天前
|
存储 安全 Java
Java一分钟之-泛型擦除与类型安全
【5月更文挑战第20天】Java泛型采用类型擦除机制,在编译期间移除泛型信息,但在编译阶段提供类型安全检查。尽管需要类型转换且可能产生警告,但可以通过特定语法避免。使用泛型时应注意自动装箱拆箱影响性能,无界通配符仅允许读取。理解这些特性有助于编写更安全的代码。
27 4
|
2天前
|
安全 Java API
Java一分钟之-泛型通配符:上限与下限野蛮类型
【5月更文挑战第19天】Java中的泛型通配符用于增强方法参数和变量的灵活性。通配符上限`? extends T`允许读取`T`或其子类型的列表,而通配符下限`? super T`允许向`T`或其父类型的列表写入。野蛮类型不指定泛型,可能引发运行时异常。注意,不能创建泛型通配符实例,也无法同时指定上下限。理解和适度使用这些概念能提升代码的通用性和安全性,但也需兼顾可读性。
25 3
|
6天前
|
安全 Java 编译器
java泛型浅谈
java泛型浅谈
7 1
|
6天前
|
存储 安全 Java
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
|
6天前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
【5月更文挑战第2天】JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
42 2
|
6天前
|
安全 Java 编译器
【JAVA】泛型和Object的区别
【JAVA】泛型和Object的区别