`
jianchen
  • 浏览: 335259 次
  • 性别: 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期末复习 (1)

    java复习 (1)

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

    Java应用程序设计之多线程和泛型 Thread、Runnable、Callable 线程操作:isAlive()、isInterrupted()、join()、sleep()、stop()、interrupted()、setDaemon()、setPriority()、yield() 同步与死锁、Object类对线程的...

    JAVA项目---网络版JQ

    为巩固对JAVA的学习,帮助大家掌握知识点,特让同学们编写一个模拟QQ在线聊天的程序JQ,可实现网上多人聊天,主要用到Swing、 线程、网络编程、集合类、文件IO处理、日期、泛型及JAVA基础知识,采用面向对象的方法...

    Java期末考试真题试卷及复习资料【高级编程】

    Java期末考试真题试卷及复习资料【高级编程】 Java高级编程期末考试真题试卷及复习资料 名词解释 泛型 答即参数化类型允许程序创建集合时指定集合元素的类型在定义方法类接口时使用类型形参类型形参将在声明变量调用...

    Java工程师面试复习指南

    【Java工程师面试复习指南】本仓库架构大部分Java工程师所需要掌握的核心知识,整合了互联网上的很多优质Java技术文章,力求打造为最完整最实用的Java开发者学习指南,如果对你有帮助,给个star告诉我吧,谢谢!...

    Java工程师必备面试题【多线程、反射、类加载器、JVM、泛型、异常处理、注解、面向对象编程、集合、IO流、序列化】

    使用场景及目标:以上Java面试题可以作为面试前的复习和准备材料,帮助求职者复习Java基础知识,加深对Java语言特性和机制的理解,提高Java编程能力和解决问题的能力,从而更好地应对Java面试。 其他说明:以上Java...

    java进阶13天资料.zip

    Java进阶13天资料 day01-复习回顾、静态、继承、引用类型使用 day02-抽象类、接口、代码块,final、单例、枚举 day03-多态、包、权限修饰符、内部类,Object类,Date类 day04-常用API、正则表达式,泛型、Collection...

    JAVA基础课程讲义

    JAVA各版本的含义 13 JAVA技术体系架构 14 JAVA的特性和优势 14 JAVA应用程序的运行机制 15 JVM(JAVA VIRTUAL MACHINE) 16 Java运行时环境JRE(Java Runtime Environment) 17 JAVA语言应用范围 18 第一个JAVA程序 18 ...

    Java期末重点复习(1)

    这几天会开一个Java期末复习的专栏,做的是关于Java特性的内容~ 这一辑的内容如下: ①类的继承 ②HashMap ③StringBuilder和StringBuffer ④ArrayList ⑤抽象类 关于资源的内容,主要是我写的一些Demo,看了比较有...

    Java领域基础部分JavaSE笔记

    Java领域基础部分aS笔记涵盖了Java编程语言的核心概念,包括但不限于: Java数据类型和变量 控制流程语句(if-else, switch, for, while等) 数组和集合 面向对象编程(OOP)基础(类,对象,继承,封装,多态) ...

    java-for-linux::fire: java-for-linux 是一个综合型开源项目,有 6+ 个开源子项目

    Java 写游戏安全、基于 Linux 的 JNI 动态函数注册、Kali Linux 内核编程、基于 Java For OpenCV 的百度云失效链接自动分享、在 JVM 源码内嵌写 Native 函数给 Java 层调用、C 语言指针、Java 泛型反编译(在开源...

    java高级知识点快速复习.zip

    集中的知识点,适用于已经学过之后,快速过一遍复习(临时抱佛脚),比如面试前复习一下。不适用于没学过这些知识点的...包括spring注解,maven,git,java集合,泛型,jdk8,jvm参数,正则表达式,sql 洁牙密码:alex

    Java 软件开发复习提纲.pdf

    java基础复习 反射、io流

    Java期末重点复习(2)

    BIT-刘滨老师的Java期末重点复习Demo第二弹 与其说是复习,不如说是从头开始学hhhh 其他细节看第一辑,这次的内容主要是: ①接口类 ②泛型(类、方法) ③匿名内部类和Lambda ④Collection 关于资源的内容,主要是...

    java面向对象程序设计课程每章ppt(共15章+复习1章).zip

    第13章 容器和泛型.pptx 第14章 流与文件(1).pptx 第14章 流与文件(2).pptx 第15章 网络编程.pptx 第1章 Java概述.pptx 第2章 Java基础.pptx 第3章 数组.pptx 第4章 类和对象(1).pptx 第4章 类和对象(2)....

    AIC的Java课程1-6章

    sjtu.com/&lt;br&gt;&lt;br&gt;此内容是Java第1到第六章的PPT,希望大家喜欢 &lt;br&gt;如果大家觉得好我继续发 &lt;br&gt;课程定位 “Java程序”课程覆盖SCJP认证所要求的知识点,是J2EE课程体系中的基础课程。本课程面向的学员...

    java8stream源码-java8-learning:通过复习OCA和OCP来学习Java8

    java8流源码Java8学习 准备 目录 高级班级设计 设计模式和原则 泛型和集合 函数式编程 日期、字符串和本地化 异常和断言 并发 输入输出 蔚来2 JDBC

    Java面向对象知识点梳理(思维导图)

    这个导图可以作为学习和复习Java面向对象编程的辅助工具。它可以用于自学、课堂教学、培训班等场景。学习者可以通过导图来整体了解Java面向对象编程的知识结构,快速定位和理解各个知识点的关系和重要性。同时,导图...

    Java基础知识加强PPT

    本文档适合对Java编程语言有一定了解的朋友复习之用,此PPT涵盖了枚举、反射、JavaBean、注解、泛型、代理等多方面的基础知识,讲解并不详细,但短小精悍,对思维发散很有好处,实用性强

    某大学往年期末考试题:Java考试(含答案).docx

    某大学往年期末考试题:Java...了解Java的集合框架和泛型,包括List、Set、Map等常见集合类型。 掌握Java的文件读写操作,包括读写文件、处理文件路径等。 熟悉Java的多线程编程,包括创建线程、同步线程、线程池等。

Global site tag (gtag.js) - Google Analytics