theme: healer-readable
highlight: a11y-dark
哈喽,各位小伙伴们,你们好呀,我是喵手。
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
在Java开发中,经常需要处理各种数据类型。但是,传统的Java使用Object类型作为通用数据类型会存在一些问题,如数据类型的转换等。Java泛型的出现就是为了解决这些问题。
摘要
本文将介绍Java泛型的基本概念、语法和应用场景。通过对源代码的分析和案例的讲解,掌握泛型的使用方法和操作技巧,同时分析泛型的优缺点,并介绍相应的应用实例。最后,通过测试用例对泛型的使用进行验证,总结泛型的特点和使用场景。
泛型
简介
Java泛型是Java 5的新特性,是一种将数据类型参数化的机制。它可以使编译器在编译时强制进行类型检查,从而提高代码的可读性和安全性。
泛型可以在类、接口、方法中定义类型参数,使得它们可以使用不同类型的对象而不需要进行数据类型转换。泛型的出现使得程序员可以编写更加通用、类型安全、可重用和简洁的代码。
源代码解析
Java泛型的关键就在于定义类型参数。Java泛型的定义采用尖括号“<>”将类型参数括在一起,如下所示:
代码语言:java复制class ClassName<T> {
// ...
}
其中,T
为类型参数,可以是任意非关键字的标识符。通过使用T
来代表类型参数,可以在类或方法内部使用该类型。通过在实例化类或调用方法时指定具体类型,可以在编译时进行类型检查。
这是一个泛型类定义,其中 T 是泛型类型参数。它表示该类可以接受任意类型的参数。在类的定义中,可以使用 T 作为类型参数定义类中的各种成员变量、方法或构造函数等。在实例化该泛型类时,会指定实际的类型参数来替换 T。例如:
代码语言:txt复制ClassName<String> instance = new ClassName<>();
这里实例化了一个 ClassName 类,其中 T 被替换为 String 类型。这意味着在该实例中,可以使用 String 类型的成员变量、方法或构造函数等。
除了类型参数,还有通配符类型参数?
,可以用来表示不确定的类型。例如:
public void printList(List<?> list) {
// ...
}
该方法接受一个List类型的参数,该List中的元素类型可以是任意类型,但是不确定具体是什么类型。
应用场景案例
集合类中使用泛型
在Java集合类中,最常见的使用泛型的地方是在List、Set和Map等容器类中。例如:
代码语言:java复制List<String> list = new ArrayList<String>();
Set<Integer> set = new HashSet<Integer>();
Map<String, Integer> map = new HashMap<String, Integer>();
这里定义了一个List类型的集合,其中只能添加String类型的元素;定义了一个Set类型的集合,其中只能添加Integer类型的元素;定义了一个Map类型的集合,其中Key的类型是String,Value的类型是Integer。
自定义泛型类和泛型方法
我们也可以自定义泛型类和泛型方法。例如,我们定义一个泛型类来表示一对数据:
代码语言:java复制class Pair<T, V> {
private T first;
private V second;
public Pair(T first, V second) {
this.first = first;
this.second = second;
}
// 省略其他代码
}
这里定义了一个类Pair
,它包含两个类型参数T
和V
,分别表示第一个数据和第二个数据的类型。我们还可以定义泛型方法来操作泛型类型:
public static <T> T getMax(T[] array) {
T max = array[0];
for (int i = 1; i < array.length; i ) {
if (array[i].compareTo(max) > 0) {
max = array[i];
}
}
return max;
}
该方法接收一个泛型数组,返回其中最大的元素。这里使用了类型参数T
表示数组中元素的类型。通过compareTo
方法比较数组中元素的大小,返回最大元素。
优缺点分析
优点
- 提高代码的可读性和安全性;
- 实现了代码的类型安全检查,减少了运行时的错误;
- 可以在编译时检查代码的类型安全,避免了数据类型转换的问题;
- 实现了代码的重用性和通用性。
缺点
- 在某些情况下,使用泛型会导致代码的可读性降低;
- 泛型的类型参数不能是基本数据类型,只能使用其对应的包装类;
- 不能使用泛型数组,只能使用泛型容器。
类代码方法介绍
泛型类
在Java中,泛型类用<T>
来替代具体的数据类型。
package com.example.javase.se.classes.generic;
import java.util.List;
/**
* @Author ms
* @Date 2023-11-05 19:10
*/
class Pair<T extends Comparable<T>, V> {
private T first;
private V second;
public Pair(T first, V second) {
this.first = first;
this.second = second;
}
public Pair() {
}
public static Integer getMax(List<Pair<String, Integer>> array) {
Integer max = array.get(0).second;
for (int i = 1; i < array.size(); i ) {
if (array.get(i).second > max) {
max = array.get(i).second;
}
}
return max;
}
@Override
public String toString() {
return "Pair{"
"first=" first
", second=" second
'}';
}
}
这里定义了一个泛型类Pair
,包含两个类型参数T
和V
,分别表示第一个数据和第二个数据的类型。通过<T, V>
声明类型参数。
该代码定义了一个泛型类Pair
,其中含有两个成员变量first
和second
,分别表示泛型类型T
和V
的第一个和第二个值。类中包含了一个有限制的泛型方法getMax
,用于返回一个列表中第二个值最大的整数。该方法使用了通配符? extends Comparable<?>
来限制泛型类型T
必须实现Comparable
接口,以便能够进行比较操作。在实例化该类时,可以指定T
和V
的具体类型,也可以不指定,使用默认值。类中还包含了一个重写的toString
方法,用于将实例对象转化为字符串。
泛型方法
在Java中,泛型方法需要在方法名前面添加类型参数列表,用<T>
来替代具体的数据类型。
public static Integer getMax(List<Pair<String, Integer>> array) {
Integer max = array.get(0).second;
for (int i = 1; i < array.size(); i ) {
if (array.get(i).second > max) {
max = array.get(i).second;
}
}
return max;
}
这里定义了一个泛型方法getMax
,它接收一个泛型数组,并返回其中最大的元素。通过<T>
声明类型参数。
通配符
通配符可以用来表示不确定的类型,写法为<?>
。例如:
public void printList(List<?> list) {
// ...
}
这里定义了一个方法printList
,它接收一个List类型的参数,该List中的元素类型可以是任何类型。
测试用例
代码语言:java复制package com.example.javase.se.classes.generic;
import java.util.ArrayList;
import java.util.List;
/**
* @Author ms
* @Date 2023-11-05 19:10
*/
public class Test {
public static void main(String[] args) {
Pair<String, Integer> p1 = new Pair<>("Java", 5);
Pair<String, Integer> p2 = new Pair<>("Python", 7);
Pair<String, Integer> p3 = new Pair<>("C ", 3);
List<Pair<String, Integer>> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
Integer maxPair = Pair.getMax(list);
System.out.println("Max Pair: " maxPair);
}
}
该测试用例测试了Pair
类和Pair
类的泛型方法getMax
。首先创建了三个Pair
对象,并将它们添加到一个List中。然后调用getMax
方法,返回其中最大的元素。
测试结果
根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。
测试代码分析
根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。
这段代码演示了如何使用泛型类Pair及其静态方法getMax来实现获取列表中最大值的功能。
首先,我们定义了三个Pair对象p1、p2、p3,这些对象分别包含了一个String类型的值和一个Integer类型的值。
接着,我们创建了一个List对象list,并向其添加了p1、p2、p3三个对象。
最后,我们调用Pair类的静态方法getMax来获取list列表中所有Pair对象中的最大值,并将结果保存在一个Integer类型的变量maxPair中。最终,我们将maxPair打印输出。
值得注意的是,因为Pair类中定义了泛型类型<T extends Comparable<T>>,所以我们才可以使用Pair类提供的getMax方法来获取最大值。此外,我们定义的列表list中的元素类型也必须与Pair对象的类型一致,即都是Pair<String, Integer>类型。
小结
本文介绍了Java泛型的基本概念、语法和应用场景。通过对源代码的分析和案例的讲解,掌握了泛型的使用方法和操作技巧,同时分析了泛型的优缺点,并介绍了相应的应用实例。最后,通过测试用例对泛型的使用进行了验证,总结了泛型的特点和使用场景。
总结
Java泛型是Java 5的新特性,是一种将数据类型参数化的机制。它可以使编译器在编译时强制进行类型检查,从而提高代码的可读性和安全性。泛型可以在类、接口、方法中定义类型参数,使得它们可以使用不同类型的对象而不需要进行数据类型转换。泛型的出现使得程序员可以编写更加通用、类型安全、可重用和简洁的代码。
... ...
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
... ...
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!