Writer:BYSocket(泥沙砖瓦浆木匠)

微博:BYSocket

豆瓣:BYSocket

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");

会发现:

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

四、小结

泥瓦匠记忆宫殿

1、在编译时检查强类型

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

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

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

Java 泛型只是编译时的概念,因为编译后类型会被擦除,还原本真。哈哈~下次说这个。

Writer:BYSocket(泥沙砖瓦浆木匠)

微博:BYSocket

豆瓣:BYSocket

Java 容器 & 泛型:六、容器讲到为什么要使用泛型的更多相关文章

  1. Java基础 -- 持有对象(容器)

    一 容器的用途 如果对象的数量与生命周期都是固定的,自然我们也就不需要很复杂的数据结构. 我们可以通过创建引用来持有对象,如 Class clazz; 也可以通过数组来持有多个对象,如 Class[] ...

  2. JAVA中的集合容器操作类

    目录 JAVA中的集合容器操作类 List集合 ArrayList的操作方法说明 LinkedList Stack Set Map Queue 总结 JAVA中的集合容器操作类 Java容器类库总共分 ...

  3. 持有对象:总结JAVA中的常用容器和迭代器,随机数 速查

    JAVA使用术语“Collection”来指代那些表示集合的对象,JAVA提供的接口很多,首先我们先来记住他们的层次结构: java集合框架的基本接口/类层次结构 java.util.Collecti ...

  4. Java的同步容器和并发容器

    前言: 之前在介绍Java集合的时候说到,java提供的实现类很少是线程安全的.只有几个比较古老的类,比如Vector.Hashtable等是线程安全的,尤其是Hashtable,古老到连命名规范都没 ...

  5. Java:常用的容器小记

    Java:常用的容器小记 对 Java 中的 常用容器,做一个微不足道的小小小小记 容器类概述 常见容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 M ...

  6. [Think In Java]基础拾遗3 - 容器、I/O、NIO、序列化

    目录 第十一章 持有对象第十七章 容器深入研究第十八章 Java I/O系统 第十一章 持有对象 1. java容器概览 java容器的两种主要类型(它们之间的主要区别在于容器中每个“槽”保存的元素个 ...

  7. Java Servlet与Web容器之间的关系

    自从计算机软件开发进入网络时代,就开始涉及到通讯问题.在客户/服务器(也叫C/S应用)时期,每个软件都有自己的客户端和服务器端软件.并且客户端和服务器端之间的通讯协议差别也很大.后来随着互联网的发展, ...

  8. JAVA同步容器和并发容器

    同步容器类 同步容器类的创建 在早期的JDK中,有两种现成的实现,Vector和Hashtable,可以直接new对象获取: 在JDK1.2中,引入了同步封装类,可以由Collections.sync ...

  9. java并发:同步容器&并发容器

    第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...

  10. Java并发——同步容器与并发容器

    同步容器类 早期版本的JDK提供的同步容器类为Vector和Hashtable,JDK1.2 提供了Collections.synchronizedXxx等工程方法,将普通的容器继续包装.对每个共有方 ...

随机推荐

  1. mongooDb链接javaapi

    mongodb链接有多种:所以不同链接下的api也不太一样. 1.api比较全面 public void query2(){ String mondburl = Config.getInstance( ...

  2. 《Linux就该这么学》第十六天课程

    今天笔记有点少就不发了,分享一下第23章 使用OpenLDAP部署目录服务很实用 下面是DHCP动态管理地址,如需深入学习请前往 https://www.linuxprobe.com/chapter- ...

  3. Redis讲解以及测试要点

    一.redis 简介 redis适合放一些频繁使用,比较热的数据,因为是放在内存中,读写速度都非常快,一般会应用在下面一些场景,排行榜.计数器.消息队列推送.好友关注.粉丝. 首先要知道mysql存储 ...

  4. [转].NET Core、Xamarin、.NET Standard和.NET Framework四者之间的区别

    转至:https://segmentfault.com/a/1190000011539920 前段时日微软(Microsoft)正式发布了.NET Core 2.0,在很多开发社区中反响不错.但还是有 ...

  5. web项目中对post请求乱码处理

    <filter> <filter-name>characterEncoding</filter-name> <filter-class>org.spri ...

  6. lucene之Field属性的解释

    Field类 数据类型 Tokenized是否分词 Indexed 是否索引 Stored 是否存储 说明 StringField(FieldName, FieldValue,Store.YES)) ...

  7. js:函数与变量作用域的提升

    一.要彻底理解JS的作用域和Hoisting,只要记住以下三点即可:      1.所有申明都会被提升到作用域的最顶上      2.同一个变量申明只进行一次,并且因此其他申明都会被忽略      3 ...

  8. Koa 学习笔记

    开始 就像官网上说的,一切框架都从一个"Hello World"开始,首先我们新建一个 package.json,内容尽量简单: { "name": " ...

  9. Linux的50个基本命令

    1.ls -a 列出当前目录下的所有文件,包括以.头的隐含文件(如-/.bashrc) ls –l 列出当前目录下文件的详细信息 2. pwd 查看当前所在目录的绝对路经 3. cd 目录之间的移动 ...

  10. VSCode插件开发全攻略(六)开发调试技巧

    更多文章请戳VSCode插件开发全攻略系列目录导航. 前言 在介绍完一些比较简单的内容点之后,我觉得有必要先和大家介绍一些开发中遇到的一些细节问题以及技巧,特别是后面一章节将要介绍WebView的知识 ...