首页 > 其他分享 >泛型

泛型

时间:2024-02-25 18:45:14浏览次数:15  
标签:子类 数据类型 类型 泛型 集合 public

 

1. 介绍

  泛型(Generics):是Java语言中一项重要特性,允许在类、接口和方法中使用参数化类型。通过泛型,可以编程通用、灵活的代码。提高代码的重用性和类型安全性。

  泛型是Java SE 1.5的新特性,是一种不确定的数据类型,这种不确定的数据类型需要我们在使用这个类的时候它才能够确定出来,早期的Object类型可以接收任意的对象类型,但是在实际的使用过程当中,会出现类型转换的问题,会报出一个异常,使用泛型就可以避免这种问题,因为泛型可以使编译器在编译期间对类型进行检查以次来提高类型安全,减少运行时由于对象类型不匹配引发的异常。

  具体来说,泛型允许我们在编写类、接口和方法时使用类型参数,而不是具体的数据类型。这些类型参数在使用时,可被指定为具体的数据类型,从而使得代码可以适用于不同类型的数据,而不必为每种类型编写单独的代码。如果不确定使用什么类型的数据就使用泛型。从概念而言就是一个预定义数据类型。

 

  优点:

  1) 类型安全性和程序健壮性:类型安全性和程序健壮性是相互关联的。泛型在编译时对类型进行检查,提高了程序的健壮性,避免在运行时由于类型转换错误而导致的异常。入:ClassCastException异常。

  ClassCastException异常是JVM在检测到两个类型转换不兼容时引发的运行时异常。

  2) 代码重用性和简洁性:代码重用性和简洁性是相互关联的。通过泛型可以编译通用的,可复用的代码来提高代码的重用性。同时泛型也使得代码更加简洁、易读;因为它消除了很多显式的类型转换和重复的代码。

  3) 减少类型转换:泛型的主要优点是减少了代码中的类型转换。

 

2. 泛型集合和非泛型集合

  泛型集合:是指能够存储特定类型对象的集合,其中的元素类型在集合被创建时是确定,并且集合只能存储该特定类型的元素。泛型集合通过泛型机制提供了类型安全的存储和检索操作。

  默认为Object类型,接受的类型可以是引用数据类型、Boolean类型。如果指定泛型类型为String类型,存储的类型只能是String类型,可以存储多个元素。

  泛型必须是包装类,只能代表引用数据类型。在程序总有些数据会返回空值,用剧本数据类型int会发生异,因为int内有null值;但基本数据类型对应的Integer包装类型不会,因为对象可以为NULL。

    // 泛型集合
    // 需要一个存储字符串的列表,并且希望这个列表能够保证类型安全,那么我们可以使用泛型集合 ArrayList。
    public static void main(String[] args) {

        // 创建一个存储字符串的泛型集合
        ArrayList<String> stringList = new ArrayList<>();

        // 向集合内添加元素
        stringList.add("Hello,");
        stringList.add("Generic.");

        // 遍历打印
        System.out.println("字符串集合内的元素:");
        for (String list : stringList) {
            System.out.println(list);
        }

        // 从集合内获取元素
        String accessElement = stringList.get(0);
        System.out.println("第一个元素为:" + accessElement);

    }

 

    // 泛型集合
    // 创建一个泛型方法,该方法接受一个泛型列表作为参数,并打印出列表中的所有元素。这样的方法可以接受任何类型的列表,并且具有通用性。
    public static void main(String[] args) {

        ArrayList<Integer> integerList = new ArrayList<>();
        integerList.add(2024);

        ArrayList<String> stringList = new ArrayList<>();
        stringList.add("Hello,2024!");

        System.out.println("整数列表:");
        printlnList(integerList);

        System.out.println("字符串列表:");
        printlnList(stringList);
    }

    // 泛型方法,接受一个泛型列表并打印其中所有元素
    public static <T> void printlnList(ArrayList<T> arrayList) {
        for (T element : arrayList) {
            System.out.println(element);
        }
    }

 

  非泛型集合:

    // 非泛型集合
    public static void main(String[] args) {

        // 非泛型集合,存储元素用Object类型,add接收的类型可以是基本数据类型,引用数据类型,布尔类型
        ArrayList<Object> nonGenericCollectionList = new ArrayList<>();

        // 列表内添加不同类型的对象
        nonGenericCollectionList.add("学Java的Bei");  // 字符串
        nonGenericCollectionList.add(20240225); // 整数
        nonGenericCollectionList.add(true); // 布尔

        // 列表内获取元素,并进行元素转换
        String string = (String) nonGenericCollectionList.get(0);
        int num = (int)nonGenericCollectionList.get(1);
        Boolean bool = (boolean)nonGenericCollectionList.get(2);

        // 打印元素
        System.out.println("string = " + string);
        System.out.println("num = " + num);
        System.out.println("bool = " + bool);
        
        //  string = 学Java的Bei
        //  num = 20240225
        //  bool = true
    }

    注意:

    •  在创建集合时指定集合存储的元素类型;例:ArrayList<Integer>表示存储整数类型的元素。
    •  遍历集合时不需行类型转换;因为集合内的元素类型已经确定。
    •  泛型集合在编写通用代码和提高代码安全性方面非常有用。

  使用非泛型集合时,需明确存储每个元素的数据类型,否则会引发 异常 ClassCastException。

 

3. 泛型类

  泛型类是使用泛型类型参数的类。允许类中某些字段、方法或构造函数接受特定类型的数据,而这些类型在类被实例化时才确定。

  泛型标识(也称为类型参数):在Java中指定泛型类,接口或方法的参数类型。允许在编写代码时使用占位符来表示数据类型,而不需提前确定具体的参数类型;当使用时,再用确定的数据类型替换我们的标识。

 

  在定义泛型类、接口或方法时,使用尖括号<T>、<E>或其他标识符来声明参数类型;这些标识符可以是任何合法的Java标识符,通常用单个大写字母表示,以表它们是参数类型。

  • <T>:通用泛型类型,通常表示任意类型;
  • <E>:集合元素泛型类型,通常表示集合中的元素类型;
  • <K,V>:映射键,值:表示键值对中键和值的参数类型;
// 泛型标识
public class GenericIdentifier<T> {

    // <T> 是一个泛型标识,它表示任意类型。
    // 在实例化 Box 类时,指定了具体的数据类型(整数和字符串),这样就替换了泛型标识,使得 Box 类可以存储不同类型的数据。

    // 下面的T仅仅表示的是一种参数类型,这个参数类型是一个变量,可以指代任意一种引用数据类型。
    // T可以换成 A-Z 之间的任何一个字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替,在可读性上可能会弱一些。

    private T date;

    public GenericIdentifier(T date) {
        this.date = date;
    }

    public T getDate() {
        return date;
    }

    public void setDate(T date) {
        this.date = date;
    }
}

 class Main {
    public static void main(String[] args) {

        // 创建一个存储整数的GenericIdentifier实例
        GenericIdentifier<Integer> integerGenericIdentifier = new GenericIdentifier<>(10);

        // 创建一个存储字符串GenericIdentifier实例
        GenericIdentifier<String> stringGenericIdentifier = new GenericIdentifier<>("学Java的Bei");

        // 获取并打印数据
        System.out.println("整数:" + integerGenericIdentifier.getDate()); // 整数:10
        System.out.println("字符串:" + stringGenericIdentifier.getDate()); // 字符串:学Java的Bei

    }
}

 

4. 从泛型类派生子类

  在Java可以从泛型类派生子类,但要注意一些限制和约束。

  1) 如果子类也是泛型类,并且使用父类的参数类型,那么子类的参数类型标识应与父类的参数类型标识一致。否则,在子类中无法得到具体的数据类型,编译器会报错。 

// 从泛型类派生子类
public class NoteOne<T> {

    // SubClass<T> 是 NoteOne<T> 的子类,并且也是一个泛型类。
    // 子类 SubClass 继承了父类 NoteOne 的类型参数 T,使得子类可以使用相同的类型参数。
    // 这样,子类可以保留父类的泛型类型,并且可以使用相同的类型参数来实例化对象。

    private T data;

    public NoteOne(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }
}

// 子类也是泛型类,且继承父类的参数类型
class SubClass<T> extends NoteOne<T>{

    public SubClass(T date) {
        super(date);    // super(data) 表示调用父类的构造方法,并将参数 data 传递给父类的构造方法进行处理。
    }
}

class Main {

    public static void main(String[] args) {

        // 创建一个存储整数的SubClass实例
        SubClass<Integer> integerSubClass = new SubClass<>(2024);
        System.out.println("整数:" + integerSubClass.getData());

        // 创建一个存储字符串的SubClass实例
        SubClass<String> stringSubClass = new SubClass<>("学java的Bei");
        System.out.println("字符串:" + integerSubClass.getData());

    }
}
    2) 如果子类不是泛型类,而父类是泛型类;那么在子类中实例化父类时,需明确指定泛型类的数据类型。这种行情况下,子类不具有泛型类型参数,而是使用具体的数据类型来实例化父类。
public class NoteTwo<T> {

    // 子类 SubBox 继承了父类 NoteTwo<T>,但子类自身不是泛型类。
    // 在子类的构造方法中,通过 super(data) 指定了父类 NoteTwo 的泛型数据类型为 Integer。
    // 这样,子类 SubBox 就可以正确地实例化父类 NoteTwo<Integer>。
    private T data;

    public NoteTwo(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }
}

// 子类不是泛类型
class SubClassTwo extends NoteTwo<Integer> {
    public SubClassTwo(Integer date) {
        super(date);    // 指定父类的泛型数据类型为Integer
    }
}

class MainTwo{

    public static void main(String[] args) {

        // 创建子类实例,需明确指定父类的泛型数据类型为Integer
        SubClassTwo subClassTwo = new SubClassTwo(20240225);

        // 调用父类方法
        System.out.println("参数:" + subClassTwo.getData());  // 参数:20240225

    }
}

 

 

标签:子类,数据类型,类型,泛型,集合,public
From: https://www.cnblogs.com/warmNest-llb/p/18032723

相关文章

  • ts泛型08
    泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性 //需求:定义一个函数,传入两个参数,第一个参数是数据,第二个参数是数量,//函数的作用:根据数量产生对应个数的数据,存放在一个数组中functionGetaArr<T>(value:T,count:......
  • Flink 使用之 TypeInformation 由于泛型类型在运行时会被JVM擦除,所以要指定类型
    Flink使用之TypeInformation由于泛型类型在运行时会被JVM擦除,所以要指定类型Flink使用介绍相关文档目录Flink使用介绍相关文档目录背景本篇从近期遇到的StreamJavaAPI问题,引出TypeInformation的使用。Exceptioninthread"main"org.apache.flink.api.common.functi......
  • JAVA基础-泛型
    1,泛型概述泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型......
  • Java之泛型系列--继承父类与实现多个接口(有示例)
    原文网址:​​Java之泛型系列--继承父类与实现多个接口(有示例)_IT利刃出鞘的博客-CSDN博客​​简介本文介绍java如何用泛型表示继承父类并实现多个接口。用泛型表示某个类是某个类的子类或者实现了接口的方法为:<TextendsA&B&C> 用法1:全都是接口。对于本例来说:A、B......
  • C# 泛型方法New泛型对象
     var frm=Activator.CreateInstance<T>(); ///<summary>//////</summary>///<typeparamname="T"></typeparam>///<paramname="pnlFrm"></param>///......
  • Java 中的泛型机制
    泛型JDK5.0之后推出的新特性:泛型泛型这种语法机制,只在程序编译阶段起作用,只给编译器参考的(运行阶段没用)使用泛型的好处:集合中存储的元素统一了从集合中取出来的元素类型是泛型指定的类型,不需要进行大量的“向下转型”泛型的缺点:集合中的元素缺乏多样性importjava.util.Ar......
  • Java泛型
    参考:磊叔的技术博客 : 聊一聊-JAVA泛型中的通配符T,E,K,V,?tutorialspoint: Java-Generics Java-泛型泛型的好处在没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参......
  • 每日一道Java面试题:说一说Java中的泛型?
    写在开头今天的每日一道Java面试题聊的是Java中的泛型,泛型在面试的时候偶尔会被提及,频率不是特别高,但在日后的开发工作中,却是是个高频词汇,因此,我们有必要去认真的学习它。泛型的定义什么是泛型?什么是泛型?这是个好问题,JDK5更新时带来了一个新特性-泛型,所谓“泛型”就是类型参......
  • Go官方放出泛型slices包
    阅读本文大概需要6分钟。slices 标准库是Go1.21新增的一个包,它提供了许多对切片(slices)进行常见操作的泛型函数,可以适用于任何元素类型的切片。切片是Go语言中一种重要的数据结构,它可以动态地存储和管理一组相同类型的元素。切片的底层实现是一个数组,但是切片可以根据需要......
  • 泛型
    泛型是一种强类型(strongly-typed)编程机制,它允许你编写具有参数化类型的代码,以便更加灵活和安全地处理不同数据类型的对象。泛型提供了编译时类型检查,这有助于在编译时捕获潜在的类型错误,而不是在运行时,在运行时泛型将会被彻底擦除。基础应用包含泛型类、泛型方法、泛型属性等,在......