Java泛型-语法与常用实例

简介: Java泛型-语法与常用实例

Java泛型

六:总结提升

一:故事背景

最近回顾了很早之前学的java基础,其中涉及到了泛型的概念,今天总结到此,以供大家参考以及自己的日后学习。


二:什么是Java泛型

在Java中,泛型是一种参数化类型的机制,它可以让类、接口、方法在定义时使用一个或多个类型参数,这些类型参数可以在实例化时被具体的类型所代替。


三:Java泛型的用法

下面将会分别写出Java泛型的用法,语法都将内含其中。


3.1泛型类

接下来我会通过定义一个泛型类来表示一个集合,可以让这个集合可以存储任何类型的对象,而不需要在定义时指定具体的类型。使用时再去指定集合中元素的类型,避免在运行时发生类型错误。


3.3.1 MyList 泛型类

public class MyList<T> {
    private List<T> list = new ArrayList<>();
    public void add(T element) {
        list.add(element);
    }
    public T get(int index) {
        return list.get(index);
    }
    public int size() {
        return list.size();
    }
}

在这个例子中,MyList 是一个泛型类,它的类型参数是 T。我们可以使用 MyList 来存储任何类型的对象,只需要在实例化时指定具体的类型即可

3.3.2 具体使用

MyList<Integer> intList = new MyList<>();
intList.add(1);
intList.add(2);
System.out.println(intList.get(0)); // 输出 1
MyList<String> stringList = new MyList<>();
stringList.add("hello");
stringList.add("world");
System.out.println(stringList.get(0)); // 输出 hello

3.2泛型接口

泛型接口是一个可以定义泛型类型参数的接口。

3.2.1 泛型接口

public interface MyList<T> {
    void add(T element);
    T get(int index);
    int size();
}

这是一个泛型接口,它定义了一个可以存储任何类型的元素的列表。在实现该接口时,需要指定具体的类型参数.

3.2.2 具体使用

public class MyIntegerList implements MyList<Integer> {
    private List<Integer> list = new ArrayList<>();
    @Override
    public void add(Integer element) {
        list.add(element);
    }
    @Override
    public Integer get(int index) {
        return list.get(index);
    }
    @Override
    public int size() {
        return list.size();
    }
}

3.3泛型方法

泛型方法是一种定义在类中但具有泛型类型参数的方法,它可以在调用时指定不同的类型参数。

3.3.1 泛型方法

public static <T> T getFirst(List<T> list) {
    return list.get(0);
}

这是一个泛型方法,它可以接受任何类型的 List 对象,并返回该列表的第一个元素。在调用时,可以指定不同的类型参数。

3.3.2 具体使用

List<Integer> intList = Arrays.asList(1, 2, 3);
Integer first = getFirst(intList); // 返回 1
List<String> stringList = Arrays.asList("hello", "world");
String firstString = getFirst(stringList); // 返回 "hello"

四:Java泛型的好处


提高代码的可读性和可维护性:使用泛型可以使代码更加简洁、易读,减少代码冗余和重复的类型检查,降低了出错的可能性。


减少强制类型转换:在使用泛型时,编译器可以自动推断类型参数,无需进行强制类型转换,这减少了编写代码时的工作量,并使代码更加优雅。


支持代码重用:泛型代码可以在多个地方重用,而不需要进行修改。例如,在集合框架中,可以使用相同的方法来处理不同类型的集合。


支持灵活的数据结构:通过使用泛型,可以创建灵活的数据结构,使其能够处理不同类型的数据。

五:使用Java泛型的注意事项

在使用Java泛型时,有一些注意事项需要注意:


泛型类型参数不能是基本数据类型:泛型类型参数只能是类或接口类型,不能直接使用基本数据类型(如int、char、boolean)。如果需要使用基本数据类型,可以使用对应的包装类(如Integer、Character、Boolean)作为泛型参数。


泛型类型参数不能使用原生态类型:原生态类型是指未指定泛型类型参数的泛型类型。例如,List是一个原生态类型,而List<String>是具有泛型类型参数的参数化类型。在使用泛型时,应尽量避免使用原生态类型,而是使用具体的参数化类型。


泛型类型参数无法在运行时获取:由于Java的泛型使用类型擦除来实现,泛型信息在编译时被擦除,无法在运行时获取。这意味着无法在运行时判断一个对象的具体泛型类型参数。因此,在使用泛型时需要注意,泛型参数的具体类型只能在编译时进行检查。


泛型数组的创建受限:Java中不允许直接创建泛型数组,例如new T[]是不合法的。这是因为Java泛型数组的创建会涉及到类型擦除的问题,无法进行安全的类型检查。如果需要创建泛型数组,可以通过创建一个Object数组,然后进行强制类型转换来实现。


泛型类型参数不能用于静态上下文:由于泛型类型参数是在实例化时确定的,而静态成员和静态方法是在类加载时就存在的,无法访问实例化的泛型类型参数。因此,静态上下文中不能直接使用泛型类型参数,可以使用通配符或将泛型参数定义在静态方法或静态成员所在的类上。


通配符的使用限制:通配符(wildcard)用于表示不确定的类型参数,包括无界通配符(?)和有界通配符(如? extends T和? super T)。在使用通配符时,需要注意,无界通配符只能用于读取,不能用于写入;有界通配符可以用于读取和写入,但受到类型边界的限制。


泛型方法和泛型类的类型参数可以独立:在泛型类中,类级别的类型参数和方法级别的类型参数是独立的,即方法中的类型参数可以与类中的类型参数不同。这使得在泛型类的方法中可以使用额外的类型参数,增加了灵活性。


泛型类型参数的擦除和桥方法:在泛型类或接口中,由于类型擦除的原因,编译器会生成桥方法来保


持多态性。桥方法是编译器生成的方法,用于在类型擦除后保持泛型方法的多态性。


这些是使用Java泛型时需要注意的一些事项。理解并正确使用泛型可以提高代码的类型安全性和重用性。同时,还可以通过阅读相关的Java泛型文档和学习材料,深入了解泛型的原理和使用技巧。


六:总结提升

总之,Java中的泛型是一种非常强大和有用的机制,它可以提高代码的可读性和可维护性,减少强制类型转换,支持代码重用,同时还可以创建灵活的数据结构,适应不同的需求!


目录
相关文章
|
16天前
|
Java 编译器 容器
Java——包装类和泛型
包装类是Java中一种特殊类,用于将基本数据类型(如 `int`、`double`、`char` 等)封装成对象。这样做可以利用对象的特性和方法。Java 提供了八种基本数据类型的包装类:`Integer` (`int`)、`Double` (`double`)、`Byte` (`byte`)、`Short` (`short`)、`Long` (`long`)、`Float` (`float`)、`Character` (`char`) 和 `Boolean` (`boolean`)。包装类可以通过 `valueOf()` 方法或自动装箱/拆箱机制创建。
24 9
Java——包装类和泛型
|
18天前
|
Java
Java——接口的使用实例
Comparable接口用于自定义类的对象比较。通过实现此接口并重写`compareTo`方法,可以定义自定义类型的比较规则。 接下来介绍了Comparator接口,它提供了一种更灵活的比较方式。通过实现Comparator接口并重写`compare`方法,可以根据不同属性定义不同的比较规则。例如,定义一个`BrandComparator`类来比较汽车的品牌。 最后,介绍了Cloneable接口,用于实现对象的克隆。实现该接口并重写`clone`方法后,可以创建对象的浅拷贝或深拷贝。浅拷贝仅复制对象本身,深拷贝则会递归复制所有成员变量。
15 4
Java——接口的使用实例
|
19天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
7天前
|
存储 Java
Java之静态(static)与实例(instance)
Java之静态(static)与实例(instance)
|
8天前
|
Java 数据安全/隐私保护
java之基本语法
java之基本语法
17 6
|
20天前
|
存储 Java
Java内置数据类型和实例的详解
Java内置数据类型分为基本和引用两类。基本数据类型包括整型(`byte`、`short`、`int`、`long`)、浮点型(`float`、`double`)、字符型(`char`)和布尔型(`boolean`),用于存储简单的数值;引用数据类型则用于存储对象的引用,包括类(如`String`)、接口和数组。掌握这两类数据类型是Java编程的基础。以下示例展示了各种数据类型的使用方法。
|
16天前
|
存储 安全 搜索推荐
Java中的泛型
【9月更文挑战第15天】在 Java 中,泛型是一种编译时类型检查机制,通过使用类型参数提升代码的安全性和重用性。其主要作用包括类型安全,避免运行时类型转换错误,以及代码重用,允许编写通用逻辑。泛型通过尖括号 `&lt;&gt;` 定义类型参数,并支持上界和下界限定,以及无界和有界通配符。使用泛型需注意类型擦除、无法创建泛型数组及基本数据类型的限制。泛型显著提高了代码的安全性和灵活性。
|
21天前
|
Java
Java实例详解
Java实例是通过类创建的对象,其核心在于将抽象的类定义转化为具体的实体。类作为对象的模板定义了属性和行为,而实例则是这些定义的具体实现。通过`new`关键字可以创建实例,并利用点运算符访问其属性和方法。实例拥有自己的生命周期,从创建到使用直至被垃圾回收机制自动清理。此外,实例变量和静态变量的区别在于前者属于单个实例,后者则为所有实例共享。理解Java实例的概念及其管理对编程至关重要。
|
26天前
|
存储 Java 容器
Java 基础语法
Java是一种面向对象的编程语言,其基础语法包括类和对象、方法、变量、控制流语句、继承和多态以及异常处理。代码需写在类中,`main()`方法是程序入口,变量用于存储数据,控制流语句控制程序执行流程,继承和多态增强代码灵活性,异常处理保证程序稳定性。掌握这些知识可帮助您编写简单的Java程序。
|
1月前
|
安全 前端开发 Java
浅析JVM invokedynamic指令与Java Lambda语法的深度融合
在Java的演进历程中,Lambda表达式无疑是Java 8引入的一项革命性特性,它极大地简化了函数式编程在Java中的应用,使得代码更加简洁、易于阅读和维护。而这一切的背后,JVM的invokedynamic指令功不可没。本文将深入探讨invokedynamic指令的工作原理及其与Java Lambda语法的紧密联系,带您领略这一技术背后的奥秘。
18 1
下一篇
无影云桌面