Java 容器 & 泛型:六、容器讲到为什么要使用泛型

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

ArrayList是集合类中无处不在的,泛型也是,泛型对集合类尤其有用。但是为啥要使用泛型?理解好了这个问题可以帮助理解相关的更多知识点。下面泥瓦匠以最简单的例子来验证这个问题。

一、泛型

泛型的目的是为了可以让更多不同类型的对象重用。没错,这样理解就太low。真正目的是为了在编译时找到bug,而不是在运行时。(编译时,指的是源代码翻译成机器识别的代码的时候。运行时,是指代码在机器中运行的时候。)泛型只存在编译时,理解这个可以帮助你更好的理解泛型。

这样,在编译时会比在运行时更容易地找到bug和修复。

二、实现没有泛型的简易版ArrayList

简易版的ArrList有个Obejct对象(因为是Object,我们可以add任意类型。)比如说,Integer 和 String的。代码如下:

?
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
29
30
31
32
33
package javaBasic.generic;
 
/**
  * 简易版ArrayList
  */
class ArrList
{
     private Object obj;
 
     public Object getObj()
     {
         return obj;
     }
 
     public void add(Object obj)
     {
         this.obj = obj;
     }
     
}
 
public class TestArrayList
{
     public static void main(String[] args)
     {
         ArrList arrList = new ArrList();
         arrList.add(1);
         arrList.add("1");
         
         Integer objInt = (Integer) arrList.getObj();
         System.out.println(objInt);
     }
}

运行可以看出会出现ClassCastException:

?
1
2
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
     at javaBasic.generic.TestArrayList.main(TestArrayList.java:30)

想问的问题是:”这Object对象属性,怎么不能强转呢?“

:编译时,代码没错的。运行main时,当set了String类型时,将结果强制转换为Integer就会报错这个错了。

泥瓦匠的记忆宫殿又来了:

1、使用泛型比那些杂乱的需要强制转换的Object代码具有更好的安全性和可读性。

2、使用泛型可以在编译时轻松找到和解决bugs

三、使用改写简易版ArrayList

使用泛型代码如下:

?
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
29
30
31
32
33
package javaBasic.generic;
 
/**
  * 简易版ArrayList
  */
class ArrList< T >
{
     private T obj;
 
     public T getObj()
     {
         return obj;
     }
 
     public void add(T obj)
     {
         this.obj = obj;
     }
     
}
 
public class TestArrayList
{
     public static void main(String[] args)
     {
         ArrList< Integer > arrList = new ArrList<>();
         arrList.add(1);
//      arrList.add("1");
         
         Integer objInt = arrList.getObj();
         System.out.println(objInt);
     }
}

这时候如果想用

?
1
arrList.add("1");

会发现:

image

这时候就是泛型大显身手的时候,也不用需要对属性 get 方法时的强制转换。其实,  Java 泛型只是编译时的概念,因为编译后类型会被擦除,还原本真。这里T就相当于Integer。

四、小结

泥瓦匠记忆宫殿

1、在编译时检查强类型

2、显示转换的消除(上面的Integer get省去)

3、更好地实现代码重用和泛型算法

4、使用泛型比那些杂乱的需要强制转换的Object代码具有更好的安全性和可读性。

相关文章
|
2月前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
3月前
|
Java API
[Java]泛型
本文详细介绍了Java泛型的相关概念和使用方法,包括类型判断、继承泛型类或实现泛型接口、泛型通配符、泛型方法、泛型上下边界、静态方法中使用泛型等内容。作者通过多个示例和测试代码,深入浅出地解释了泛型的原理和应用场景,帮助读者更好地理解和掌握Java泛型的使用技巧。文章还探讨了一些常见的疑惑和误区,如泛型擦除和基本数据类型数组的使用限制。最后,作者强调了泛型在实际开发中的重要性和应用价值。
69 0
[Java]泛型
|
3月前
|
存储 安全 Java
🌱Java零基础 - 泛型详解
【10月更文挑战第7天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
23 1
|
3月前
|
Java 语音技术 容器
java数据结构泛型
java数据结构泛型
33 5
|
3月前
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
24 1
|
3月前
|
存储 Java 编译器
【用Java学习数据结构系列】初识泛型
【用Java学习数据结构系列】初识泛型
26 2
|
3月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
101 3
|
3月前
|
安全 Java 编译器
Java基础-泛型机制
Java基础-泛型机制
33 0
|
7月前
|
Java API 容器
Java泛型的继承和通配符
Java泛型的继承和通配符
45 1
|
8月前
|
安全 Java API
Java一分钟之-泛型通配符:上限与下限野蛮类型
【5月更文挑战第19天】Java中的泛型通配符用于增强方法参数和变量的灵活性。通配符上限`? extends T`允许读取`T`或其子类型的列表,而通配符下限`? super T`允许向`T`或其父类型的列表写入。野蛮类型不指定泛型,可能引发运行时异常。注意,不能创建泛型通配符实例,也无法同时指定上下限。理解和适度使用这些概念能提升代码的通用性和安全性,但也需兼顾可读性。
74 3