跟随狂神学Java-23,泛型、自动推断机制、自定义泛型
AI-摘要
切换
Tianli GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
跟随狂神学Java-23,泛型、自动推断机制、自定义泛型
joker2yue跟随狂神学Java
作者:joker2yue
链接:https://github.com/Joker2Yue/Joker2Yue-Blog
来源:Github
著作权归原作者所有。商业转载请联系原作者获得授权,非商业转载请注明出处。
第二十三天:泛型、自动推断机制、自定义泛型
“基础决定你未来的高度”
学习内容
泛型(相当于C++模板类,可以参照学习)
不使用泛型之前(Java5),分析程序存在缺点
1 | package com.joker_yue.javalearn.DataStruct; |
上述程序中,我们无法做到集合中的类型相同,其中一个是Cat类一个是Bird类。
什么情况下使用泛型?
如果我们想只要其中是Animal类,我们就可以使用泛型
1 | package com.joker_yue.javalearn.DataStruct; |
需要注意
- 使用JDK5之后的泛型机制
- 泛型这种语法机制,只会在程序编译时候起作用,只是给编译器看的
- 使用了泛型好处是什么?
第一,集合中储存的元素类型统一了
第二,从集合中取出的元素类型是泛型指定的类型,不需要进行大量的“向下转型” - 泛型的缺点是什么?
导致集合中的元素缺乏多样性
大多数业务中,集合中元素类型还是统一的,所以这种泛型特性被大家所认可
自动推断机制
有些时候我们觉得在迭代器迭代的时候总是需要主动去转换Obj类型,很麻烦,于是我们就使用迭代器泛型
1 | package com.joker_yue.javalearn.DataStruct; |
其中特别标注位置,使用了自动推断机制,其严格书写应为List<Animal> myList = new ArrayList<Animal>()
迭代器泛型
如果迭代器不加泛型,next()的返回值类型就是Object
迭代器用泛型后,作用不是筛选,只是转换,转换为我们想要的类型。
1 | List<String> strList = new ArrayList<>(); |
泛型可以节约代码量
自定义泛型
其实泛型的本质就是:数据类型参数化
假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?
答案是可以使用 Java 泛型。
使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。
下面描述的是将不同类别的数组进行元素输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public class GenericMethodTest
{
// 泛型方法 printArray
public static < E > void printArray( E[] inputArray )
{
// 输出数组元素 这里是增强for循环。实际上增强for循环就是隐式的调用了Iterator
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}
public static void main( String args[] )
{
// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println( "整型数组元素为:" );
printArray( intArray ); // 传递一个整型数组
System.out.println( "\n双精度型数组元素为:" );
printArray( doubleArray ); // 传递一个双精度型数组
System.out.println( "\n字符型数组元素为:" );
printArray( charArray ); // 传递一个字符型数组
}
}1
2
3
4
5
6
7
8整型数组元素为:
1 2 3 4 5
双精度型数组元素为:
1.1 2.2 3.3 4.4
字符型数组元素为:
H E L L O现在我们需要限制传入参数为指定类型,也可以使用泛型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.joker_yue.javalearn.DataStruct;
public class GenericTest03 <GenericName>{ //尖括号中是标识符随便写
public void doSome(GenericName o){ //提供了一个方法,其中的参数类型必须是GenericName类型。
System.out.println(o);
}
public static void main(String[] args) {
// new对象的时候规定了泛型是 String类型
GenericTest03<String> gt = new GenericTest03<>();
// 所以传doSome参数的时候也只能是String类型
gt.doSome("abc");
//类型不匹配
//gt.doSome(100);
// ==========================================
GenericTest03<Integer> gt2 = new GenericTest03<>();//规定泛型用Integer,doSome方法就得用Integer
gt2.doSome(100);
//类型不匹配
//gt2.doSome("abc");
}
}这里也是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package com.joker_yue.javalearn.DataStruct;
public class GenericTest03 <GenericName>{ //尖括号中是标识符随便写
public void doSome(GenericName o){ //提供了一个方法,其中的参数类型必须是GenericName类型。
System.out.println(o);
}
public static void main(String[] args) {
MyIterator<String> mi = new MyIterator<>(); //创建为String
String s1 = mi.get(); //mi1.get()返回String类型
MyIterator<Animal> mi2 = new MyIterator<>(); //创建为Animal
Animal a = mi2.get(); //mi1.get()返回Animal类型
}
}
class MyIterator<T>{
public T get() {
return null;
}
}如果强制不使用泛型的话,就会返回Object类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package com.joker_yue.javalearn.DataStruct;
public class GenericTest03 <GenericName>{ //尖括号中是标识符随便写
public void doSome(GenericName o){ //提供了一个方法,其中的参数类型必须是GenericName类型。
System.out.println(o);
}
public static void main(String[] args) {
// 当然你要强制不适用泛型的话,就会返回为Object类型
GenericTest03 gt3 = new GenericTest03();
gt3.doSome(new Object());
}
}
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果