`
jianchen
  • 浏览: 344849 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java基础复习(13)--java泛型

阅读更多

泛型:
public static <T> T gMethod(List<T> list){.....}
这种语法和generic classes有相当程度的不同:泛型符号<T>必须加在class名称之后,却必须加在method名称(及回传型别)之前。


jdk1.5还允许将“不被method实际用到”的型别参数以符号‘?’表示,例如:

 

public static List<?> gMethod(List<?> list){
    return list;//本例简单地原封不动传回
}
 


此例gMethod()接受一个List(无论其元素型别是什么),传回一个list(无论其元素型别是什么)。由于不存在(或说不在乎)型别参数(因为metho内根本不去用它),也就不必如平常一般在回传型别之前写出<T>来告知编译器了。

参数化型别的序列化:
将LikedList<Integer>得list序列化到文件中,然后读出,不过以下转换jdk1.5编译器会发出警告:


LinkedList<Integer> list1 = (Linkedlist<Integer>)in.readObject(); 告诉我们“unchecked cast”(jdk1.4则直接报错)


其他形式也不可以,比如:

 

LinkedList list1 = (LinkedList<Integer>)in.readObject();
 

只能写成这样:

 

LinkedList list1 = (LinkedList)in.readObject();


以上事实告诉我们,当object被写入文件,即失去其泛型型别参数(如果有的话)。因此读回的只是非泛型的class信息

 

如果上面的代码改写如下:

 

ArrayList list2 = (ArrayList)in.readObject();//可以顺利编译,在编译器的眼里是没问题的,但在执行时会出现异常,报类转换异常。
 

 

将对象序列化后,在序列化文件中记录的类的名称是java.util.LinkedList,并一并记录了元素型别java.lang.Integer(及其base class java.lang.Number).这些记录对于反序列化过程中恢复容器原型和内容有其必要,但无法让编译器推论当初使用的是LinkedList容器或是LinkedList<Integer>容器。

 

 

 

如果collection被参数化,则Iterator也应该使用相同的参数。

 List list = new ArrayList();
        list.add("1");
        list.add("2");
        list.add("3");
        for(Iterator<String> itr = list.iterator();itr.hasNext();){
            String s = itr.next();
            System.out.println(s);
        }
 


以上代码编译和运行都没有问题。

List list = new ArrayList();
        list.add(1);//加入的是数值,但在后面的iterator中,却期望的是String类型。
        list.add("2");
        list.add("3");
        for(Iterator<String> itr = list.iterator();itr.hasNext();){
            String s = itr.next();
            System.out.println(s);
        }
 

以上代码编译没问题,但是在运行时出现类转换异常。所以在你将Iterator参数化得同时最好也参数化你的Collection,避免出现以上问题。

Map<String,List<List<int[]>>> map = getMap();

 

从这个map中取值会很抽象,int value = map.get(someKey).get(0).get(0)[0];
你无须对list做转换,而是让编译器来帮你拆解你的parameterized type。

 

 

Generic与类型转换
合法:

LinkedList<Integer> intList = new LinkedList<Integer>();
List<Integer> moreFloats = intList;
 


非法:
LinkedList<Number> numberList = intList;
分析(了解两件事情):


1,numberlList.add(1.2);//当从中取出并被当做一个int来使用时会导致一个ClassCastException
**在类型转换中要被考虑的所来自的基础类型,而不是参数类型**


2,“擦除”的概念。java中的generic是个编译期的程序,且所有的分类信息是在编译期被处理的。一旦class被编译过后,分类信息会被擦出掉。考虑下面两个声明:

 

List<Stirng> strings = new LinkedList<String>();
List<Integer> ints = new LinkedList<Integer>();

 

信息是用在编译期以执行类型检查,但分类信息在运行时就被舍弃了。因此,对jvm来说,这些声明就变成了:

List strings = new LinkedList();
List ints = new LinkedList();

 

现在没有类型参数了,在看看原来的代码 :

List<Integer> ints = new LinkedList<Integer>();
List<Number> nums = ints;


这在编译期看起来可能还OK,但在运行时它们是两个list,其中一个打算要转换成另一个,毫无任何的类型安全性。

抑制类型安全性:

 

List<Integer> ints = new LinkedList<Integer>();
//扩张它(为了向后兼容)
List oldList = ints;
//这一行应该是不合法的,但编译和运行后会过关。
oldList.add("hello");//我的想法:转换之后,它就不会有ints成员变量所具有的Integer的限制,List的元素默认是object了

 

ereasure移除了所有的参数化,只有在运行时,当要iterating该list来打印时,问题才会显露出来。

有时也会用到简单的旧式List,Map或其他没有被参数化的时候。这回引发unchecked错误,除非你才用了generic通配符。
在Eclipse下

List list = new ArrayList();//显示类型不确定的警告
解决方法:
List<?> list = new ArrayList<?>();//现在的语法已经表明---任何类型都是可以接受的,且unchecked警告也不见了。

 

合法的写法:

 

List<Integer> list = new LinkedList<Integer>();
List<?> test = list;

 

因为你已经将list声明为List<?>,现在get()返回的是一个object,那已经非常接近java中的“unknown”。虽然是同样的类型,但这与一个仅能够使用Object的List<Object>是非常不同的,更诡异的事情发生在add()与其他采用符合该collection类型参数的method上面。因为编译器无法检查以确保类型安全性,所以它会拒绝对List<?>的add(),addAll()与set()所做的任何调用。换言之,将generic类型赋予通配符会使其基本上并成只读的。

分享到:
评论

相关推荐

    java-java面试题库整理-基础-JVM-线程并发-框架等.zip

    这份"java-java面试题库整理-基础-JVM-线程并发-框架等.zip"文件提供了一个全面的复习资源,帮助求职者准备Java相关的面试。 1. **Java基础知识** - 类与对象:Java是一种面向对象的语言,了解类的定义、构造器、...

    Java基础与实践-源代码.rar

    【Java基础与实践】是Java学习的重要组成部分,涵盖了语言的基础概念到实际应用的各个层面。这份压缩包"Java基础与实践-源代码.rar"显然包含了多个章节的学习资源,每个章节以"ch"开头的文件名代表不同的主题。下面...

    Java 基础核心总结-副本

    这份"Java基础核心总结_副本"的资料,很可能是对Java语言基础知识的全面梳理,旨在帮助学习者或面试者巩固和复习Java的核心概念。下面将根据标题和描述,结合常见的Java基础知识,来展开详细讲解。 一、基础语法 ...

    Java期末复习||应用程序设计-多线程和泛型

    Java中的多线程和泛型是程序设计中的关键概念,它们极大地增强了代码的并发性和可复用性。在Java中,实现多线程有两种主要方式:一是通过继承`Thread`类,二是通过实现`Runnable`接口。通常推荐使用实现`Runnable`...

    Java基础知识总结 - 超详细篇收藏.zip

    这份“Java基础知识总结 - 超详细篇收藏”压缩包包含了关于Java编程的基础知识,是学习和复习Java语言的理想资源。以下是对其中可能涵盖的知识点的详细解释: 1. **Java环境搭建**:学习Java的第一步是安装JDK...

    java 考试资料--第七组

    4. `JAVA复习题201002.xls`:这份资料对应2010年2月的复习题目,可能涵盖Java SE(标准版)的核心特性,如异常处理、泛型、枚举、注解、IO与NIO、Lambda表达式(如果是Java 8以后的考试)等。 这些Excel文件是备考...

    JAVA程序员必读--基础篇

    Java编程语言是软件开发领域广泛使用的编程语言,尤其在企业级应用中占据着主导地位。作为Java程序员,掌握基础..."JAVA程序员必读--基础篇"的CHM文件应该包含了这些内容的详细讲解,是学习和复习Java基础的宝贵资源。

    Java基础考试复习资料

    这份"Java基础考试复习资料"涵盖了初学者需要理解的重要概念,旨在帮助广大备考者有效地准备Java相关的考试。以下是一些关键知识点的详细说明: 1. **Java简介**:Java是由Sun Microsystems公司开发的一种跨平台、...

    Java详细复习提纲

    复习Java,首先需要理解其基本概念和技术要点。 一、Java基础知识 1. Java语言的特点: - 跨平台性:Java代码通过JVM(Java虚拟机)实现“一次编写,到处运行”。 - 面向对象:Java支持类、对象、封装、继承、...

    Java基础尚硅谷宋红康学习笔记

    【Java基础】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年发布。Java以其“一次编写,到处运行”的特性,成为跨平台应用开发的首选语言。Java的基础部分主要包括...

    Java程序设计--复习要点.doc

    本篇复习要点主要涵盖了Java语言的基础知识,包括其特点、运行机制、程序开发流程、程序分类以及语言基础,如关键字、数据类型、运算符、语句结构等。 1. **Java语言特点**: - **简单**:Java设计时考虑了C++的...

    Java基础知识复习资料.rar

    这份“Java基础知识复习资料”涵盖了学习Java编程所必需的关键概念和技术,旨在帮助初学者巩固基础,同时也适合有经验的开发者进行回顾。 1. **Java语法基础** - **变量与数据类型**:Java提供了基本数据类型(如...

    硅谷java基础每日复习eDiary

    在“硅谷java基础每日复习eDiary”这个资源中,我们涵盖了Java编程语言的基础和高级概念,这将有助于深入理解并提升Java编程技能。以下是基于描述中提到的两个文件——"Java基础每日复习笔记-JavaSE基础阶段.edf"和...

    【Java面试资料】-(机构内训资料)上海-拼多多-Java高级

    这份资料全面覆盖了Java高级开发所需的知识点,对于希望在上海拼多多或其他公司从事Java开发的求职者来说,是一份宝贵的复习资源。通过深入学习和理解这些内容,可以显著提高面试成功率,并在实际工作中展现出更高效...

    JAVA基础复习资料

    这份“JAVA基础复习资料”涵盖了初学者需要掌握的核心概念,也是经验丰富的开发者回顾基础的宝贵资源。下面,我们将深入探讨这10个章节的主要知识点。 1. **第一章:Java简介** Java的历史、设计哲学以及其在软件...

    java学习笔记-----给java初学者

    这份笔记涵盖了从基础概念到高级特性的全面内容,是学习和复习Java知识的理想工具。 1. **Java简介** Java是一种跨平台、面向对象的编程语言,由Sun Microsystems(现为Oracle公司)于1995年推出。它的“一次编写...

    【Java面试资料】-Java面试准备指南

    这份【Java面试资料】-Java面试准备指南包含了丰富的Java知识,旨在帮助你全面、系统地复习和准备Java面试。以下是一些关键的知识点: 1. **Java基础** - 数据类型:理解基本数据类型(如int、double)和引用数据...

    Java复习大纲

    以上就是Java复习大纲的主要内容,涵盖了从基础语法到进阶特性的全方位知识。在复习过程中,应注重理论与实践相结合,通过编写实际项目来巩固和深化理解。同时,随着技术的不断发展,持续关注Java的新特性和最佳实践...

    JAVA书本复习题答案整合

    1. **Java基础知识**:复习题可能涵盖了Java的基础语法,如变量、数据类型、运算符、控制结构(if-else、switch、for、while等)、方法的定义和调用、类与对象的概念、封装、继承和多态等。答案解析能帮助你快速校验...

    Java SE 复习资料

    这些知识点通常会出现在公司内部的JAVA基础复习题中,通过练习这些题目,开发者可以巩固理论知识,提升实际编程技能。每个xls文件可能包含了针对上述知识点的不同题目,通过解答,可以帮助你更好地准备公司的Java...

Global site tag (gtag.js) - Google Analytics