java编程之泛型
java泛型实现了“参数化类型”的概念,所谓“参数化类型”是指将操作的数据类型指定为一个参数,这点在容器中用的最多,例如:List<String> strlist=new ArrayList<String>(),List<Integer> intlist=new ArrayList<Integer>();strlist可以操作的数据类型是String类型,intlist可以操作的数据类型是int类型,泛型在容器中得到了充分的应用。
泛型是使得代码重用得到很大的提升,我们在程序中也会想一些办法设计代码重用的方法,例如输出一个内容,我们要用System.out.println(...),敲这么多东西还是麻烦,我们可以定义一个println()方法,如下:
static void println(Object o){
System.out.println(o);
}
再在程序中输出东西时,只需调用println(...)即可,这个println()方法就有了“泛化”的机制,它可以输出任何System.out.println()可以输出的东西,该方法的参数类型被设置为基类Object类型,我们知道,Java中的基本数据类型都有相对应的类类型的数据,比如int类型的数据对应的有Integer类类型的数据,java有“自动装箱”功能,也就是将对应的基本类型的数据转化为对应类类型的对象,例如上面的println(3),在编译后会变成println(Integer.valueOf(3));而所有的java类都是继承自Object类,所以当然可以用println()方法了。
那么将数据类型都定义为Object类型不就可以设计一个泛化类型的方法,类和接口了吗?答案是可以的,但是“太泛化”了,以至于没了边界。这里先给出代码:
public class gen{
public static void main(String[] args){
myList list=new myList();
list.push("helloworld");
list.push(12);
Object val;
while((val=list.pop())!=null){
System.out.println(val.getClass());
}
}
}
class myList{
class Node{
Object val=null;
Node next=null;
Node(Object val,Node next){
this.val=val;
this.next=next;
}
Node(){
val=null;
next=null;
}
boolean end(){
return val==null && next==null;
}
}
private Node top=null;
myList(){
top=new Node();
}
//插入新值
public void push(Object val){
top=new Node(val,top);
}
//返回头结点的值
public Object pop(){
Object val=top.val;
if(!top.end()){
top=top.next;
}
return val;
}
}
我们自定义了一个list链表,为了使这个链表有更好的普遍使用性,我们将链表类内部的数据定义为Object类型,这样我们可以插入String类型数据、int类型数据....。但是这个设计“太泛化”了,你甚至可以“混插”,比如上面的执行结果,int类型的数据和String类型的数据插到了一起,显然在后续的操作中可能出现错误,例如你创建了一个自以为全是int类型的链表并对它们求和,但是不小心插入了字符串类型的数字"123",程序编译也能通过,你以为你的程序是对的,结果运行的时候出错了!你深受打击,自挂东南枝,全球计算机行业从此一蹶不振.....
为了防止上面悲剧的发生,我们还是希望错误在编译时期就能暴露出来,以便将错误及时地扼杀与萌芽状态,泛型设计的一项重大功能体现出来了:提前指定我们的链表可以插入什么样的数据类型,并由编译器验证其类型的正确性!这时,我们可以这样设计:
public class gen{
public static void main(String[] args){
//这里指定list2中的数据类型为String类型,也就是将T设置为String类型
myList2<String> list2=new myList2<String>();
list2.push("hello world");
list2.push("hello code");
//list2.push(23);//编译时便会提醒错误
String s;
while((s=list2.pop())!=null){
System.out.println(s);
}
}
}
class myList2<T>{
class Node<U>{
U val=null;
Node<U> next=null;
Node(U val,Node<U> next){
this.val=val;
this.next=next;
}
Node(){
val=null;
next=null;
}
boolean end(){
return val==null && next==null;
}
}//这里将Node中的值类型设定为U类型,也就是将U传递给T
private Node<T> top=null;
myList2(){
top=new Node<T>();
}
public void push(T val){
top=new Node<T>(val,top);
}
public T pop(){
T val=top.val;
if(!top.end()){
top=top.next;
}
return val;
}
}
当我们不小心执行list2.push(23)时,编译器在编译阶段就会提醒:你错啦!于是我们很愉快地就可以将错误的代码修正过来。
Java容器类可以说是Java代码重用设计的一个重要体现,而Java容器类设计的基础就是泛型,这就是Java泛型的重要之处。
注:以上代码设计部分参考自《Thinking In Java》,感谢Bruce Eckel。
java编程之泛型的更多相关文章
- 黑马程序员:Java编程_泛型
=========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== 没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中.使用 ...
- Java编程思想-泛型-泛型方法
代码示例如下: package generics; //: generics/GenericMethods.java public class GenericMethods<A> { // ...
- Java编程思想-泛型-简单泛型例子
基本类型无法做为类型参数 代码如下: /** * */ package test.thinkinjava.Generics; import java.util.ArrayList; import ja ...
- java编程思想-泛型思维导图
- Java 中的泛型详解-Java编程思想
Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的 ...
- Java中的泛型 --- Java 编程思想
前言 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...
- 第九节:详细讲解Java中的泛型,多线程,网络编程
前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...
- Java编程的逻辑 (35) - 泛型 (上) - 基本概念和原理
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
- Java编程的逻辑 (36) - 泛型 (中) - 解析通配符
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
随机推荐
- linux sort命令详解(转)
sort命令是帮我们依据不同的数据类型进行排序,其语法及常用参数格式: sort [-bcfMnrtk][源文件][-o 输出文件] 补充说明:sort可针对文本文件的内容,以行为单位来排序. 参 数 ...
- 从零到实现Shiro中Authorization和Authentication的缓存
本文大纲 一.简介 二.缓存的概念 三.自定义实现缓存机制 四.什么是Ehcache 五.Ehcache怎么用 六.Spring对缓存的支持 七.Spring+Ehcache实现 八.Spring+S ...
- 浅谈MVC页面之间参数传递
关于MVC页面之间的传值,有多种方式,下面,我们就Html.RenderAction 方式 和 Html.RenderPartial 方式 来给大家分享一下有什么不同. 一.Html.RenderAc ...
- PHP弱类型语法的实现
PHP弱类型语法的实现 前言 借鉴了 TIPI, 对 php 源码进行学习 欢迎大家给予意见, 互相沟通学习 弱类型语法实现方式 (弱变量容器 zval) 所有变量用同一结构表示, 既表示变量值, 也 ...
- javascript——数据类型
在内存中,分为栈.堆.代码段.静态区,为了快速处理复杂的代码,在不同的区间储存不同的数据类型. 数据类型分为初始类型与引用类型,初始类型在栈中存储,变量赋值传值不传址,引用类型在堆中存储,传址不传值. ...
- jquery中is()函数
is(expr)函数判断当前Jquery对象所匹配的元素是否存在.只要其中一种符合,就返回 true,否则返回 false. 如果 expr是个字符串,既视为Jquery的选择器,用于表示选择的元素. ...
- 学习java的感受
学习java有一段时间了,发现现在只是才了解java,还在门槛外边. 有时候真感觉这是不是一种外星语言,各种方法各种类各种借口,总是傻傻分不清. 学过的知识过一个星期就开始模糊,有时半夜睡不着的时候 ...
- java线程(三)
线程代码同步与线程锁 为什么要有同步代码块? 线程同步的出现是为了解决多个线程对统一资源操作而引发的数据混乱问题.这里引用一个经典demo-银行转账操作,场景如下,小明的账户目前有1000人民币,他在 ...
- IOS开发常见错误
. 问题表现:什么情况?方法居然无法拉线? 问题简述:ios的空间拉线到一个.h .m文件中 居然多次拖动无效.. 问题解决:ios的空间响应单单在代码中创建一个方法是没用的,这个时候通常跟空间是没有 ...
- 产品经理学Python:for循环、while循环
Python中有两种循环,分别为:for循环和while循环. 1. for循环 for循环可以用来遍历某一对象(遍历:通俗点说,就是把这个循环中的第一个元素到最后一个元素依次访问一次).for循环的 ...