一. 泛型概念的提出(为什么需要泛型)?

首先,我们看下下面这段简短的代码:

//import java.util.List;

public class GenericTest {

    public static void main(String[] args) {
List list = new ArrayList();
list.add("语文");
list.add("数学");
list.add(100); //编译错误 for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i); //
System.out.println("name:" + name);
}
}
}

定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,很容易出现类似于//1中的错误。因为编译阶段正常,而运行时会出现“java.lang.ClassCastException”异常。因此,导致此类错误编码过程中不易发现。

在如上的编码过程中,我们发现主要存在两个问题:

1.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

2.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。

那么有没有什么办法可以使集合能够记住集合内元素各类型,且能够达到只要编译时不出现问题,运行时就不会出现“java.lang.ClassCastException”异常呢?答案就是使用泛型。

二.什么是泛型?

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

看着好像有点复杂,首先我们看下上面那个例子采用泛型的写法。

public static void main(String[] args) {

        List<String> list = new ArrayList<String>();//

        list.add("语文");
list.add("数学");
list.add("英语");
//list.add(100);//1 编译错误 //输出
for(int i=0 ; i<list.size();i++){
String subjectName = list.get(i);//
System.out.println("科目名称:"+subjectName); }
}

1. 程序//1处试图将一个Integer对象添加到list集合中,程序将无法通过编译,报出:
    java.lang.Error: Unresolved compilation problem
    因为list只接受String对象作为元素,所以//1处代码在编译时会得到错误提示

2.所以要使用泛型,如程序2处创建一个特殊的List集合:list,这个List集合只能保存字符串对象,不能保存其他类型的对象
   创建这种特殊集合的方式是:在集合接口、类后增加尖括号,尖括号里放一个数据类型,即表示这个集合接口、结合类只能保存特定类型的对象
   如//2处的类型声明,它指定:list不是一个任意的list,而是一个String类型的list,写作List<String>.我们认为list是带一个类型参数的泛型接口

3.程序在//3处不需要进行强制类型转换,因为list对象可以“记住”它的所有集合元素都是String类型

结合上面的泛型定义,我们知道在List<String>中,String是类型实参,也就是说,相应的List接口中肯定含有类型形参。且get()方法的返回结果也直接是此形参类型(也就是对应的传入的类型实参)。

三、JAVA 7泛型的“棱形”写法

在java 7以前,如果使用带泛型的接口、类定义变量,那么调用构造器创建对象时构造器的后面也必须带泛型,则显得有些多余,例如:

List<String> strList = new ArrayList<String>();
Map<String ,Interger> scores = new HashMap<String ,Integer>();

上面两条语句中的粗体代码部分是完全多余的,在java 7以前这是必需的,不能省略。java 7以后,只要给出一对尖括号(<>)即可,java可以
推断出尖括号里应该是什么泛型信息。即上面两条语句可以改为如下形式:

List<String> strList = new ArrayList<>();
Map<String ,Interger> scores = new HashMap<>();

因而简化代码:

List<String> list = new ArrayList<>();//

        list.add("语文");
list.add("数学");
list.add("英语");
//list.add(100);//2 //输出
for(int i=0 ; i<list.size();i++){
String subjectName = list.get(i);//
System.out.println("科目名称:"+subjectName); }

Double泛型:

   List<Double> list = new ArrayList<>();//

        list.add(10.1);
list.add(10.2);
list.add(10.3);
//list.add(100);//1 //输出
for(int i=0 ; i<list.size();i++){
Double subjectName = list.get(i);//
System.out.println("科目成绩:"+subjectName); }

键值对:

java中的map其实就是以键值对形式的存放数据的容器,其常用的实现类主要是哈希map
例如:
Map map = new HashMap();
插入元素:map.put("key", obj); 
移除元素: map.remove("key");
清空: map.clear();

import java.util.HashMap;
import java.util.Map;

Map<String,Double> list = new HashMap<>();//

        list.put("语文",10.1);
list.put("数学",10.1);
list.put("英语",100.0);
String arr[]={"语文","数学","英语"}; //输出
for(int i=0 ; i<list.size();i++){
Double subjectName = list.get(arr[i]);//必须是键值对
System.out.println("科目成绩:"+subjectName); }

java泛型简单学习的更多相关文章

  1. (一)关于java泛型的学习总结(泛型方法、泛型擦除)

    目录概要 一.泛型方法 二.利用泛型方法的特性实现代码的简化 三. 关于泛型的擦除 四.无界通配符和原生类型区别 五.转型和警告   泛型 一般的类中的属性或方法的参数,只能使用具体的类型:要么是基本 ...

  2. java clone简单学习

    最近在帮忙写单侧的时候,经常会和这几个对象类打交道,因为对java也不是很熟悉,刚好学习一下,都是很浅的学习,并没有深入的去学习哈,因为感觉也用不上. protected Object clone() ...

  3. Java泛型简单理解

    优点1: 没有使用泛型,向list集合中添加非字符串,运行时会报错:类型不匹配 ObjectList.java: package cn.nxl2018; import java.util.ArrayL ...

  4. Java注解简单学习

    注解(也被称作元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们在稍后某个时刻可以很方便的使用这些数据,其在一定程度上将元数据与源代码文件结合在一起,而不是保存在外部文档中. 注解使我们可以 ...

  5. Java抽象类简单学习

    使用抽象类应该注意的几个要点: 包含一个或者多个抽象方法的类必须被声明为抽象类. 将类声明为抽象类,不一定含有抽象方法. 通常认为,在抽象类中不应该包括具体方法,建议尽量将通用的域和方法放在超类中. ...

  6. java 泛型简单使用

  7. Java学习笔记(二一)——Java 泛型

    [前面的话] 最近脸好干,掉皮,需要买点化妆品了. Java泛型好好学习一下. [定义] 一.泛型的定义主要有以下两种: 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个 ...

  8. Java泛型学习笔记 - (七)浅析泛型中通配符的使用

    一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List< ...

  9. Java泛型学习笔记--Java泛型和C#泛型比较学习(一)

    总结Java的泛型前,先简单的介绍下C#的泛型,通过对比,比较学习Java泛型的目的和设计意图.C#泛型是C#语言2.0和通用语言运行时(CLR)同时支持的一个特性(这一点是导致C#泛型和Java泛型 ...

随机推荐

  1. Spring自学教程-声明式事务处理(六)

    Spring事务处理分两种: 一.编程式事务:在程序中控制事务开始,执行和提交: 1.1 使用TransactionTemplate, 使用回调函数执行事务,不需要显示开始事务,不需要显示提交事务,但 ...

  2. HDU 5620 KK's Steel

    想了一下发现是斐波那契数列.....水题 #include <stdio.h> #include <algorithm> #include <string.h> # ...

  3. CodeForces 625B War of the Corporations

    暴力匹配+一点判断 #include <stdio.h> #include <algorithm> #include <string.h> #include < ...

  4. 为什么无线信号(RSSI)是负值(转)

    源:为什么无线信号(RSSI)是负值 为什么无线信号(RSSI)是负值 答:其实归根到底为什么接收的无线信号是负值,这样子是不是容易理解多了.因为无线信号多为mW级别,所以对它进行了极化,转化为dBm ...

  5. [转]配置 VIM 的 Go 语言开发环境

    本文是针对像我这样的 VIM 小白而写的,所使用的 VIM-GO 插件虽然步骤简单但不够详细,特写此文以做记录和分享.欢迎各位大神纠正补充! 特别说明 本博文不是 Go 语言环境搭建教程,只是 VIM ...

  6. 再次写了第一个servlet

    费时2小时,熟悉tomcat和编写了第一个servlet

  7. highcharts设置Y轴范围及根据Y轴范围设置不同颜色

    yAxis : { title : { text : '数据' }, plotLines : [ { value : 0, width : 1, color : '#808080' } ], min: ...

  8. localStorage eval script

    var globalEval =function(data) { (window.execScript || function(data){ window.eval.call(window,data) ...

  9. Sublime Text3 常用快捷键动画演示及优秀插件分享

    Sublime Text 是前端的一个神器,以其精简和可DIY而让广大fans疯狂.好吧不吹了直入正题 -_-!! 首先是安装,如果你有什么软件管家的话搜一下就好,一键安装.然后,有钱的土豪就自己买个 ...

  10. Brackets - 强大免费的开源跨平台Web前端开发工具IDE (HTML/CSS/Javascript代码编辑器)

    Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由 Adobe 创建和维护,根据MIT许可证发布,支持 Wind ...