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:/ ...
随机推荐
- 雷达的L、S、C、X波段是什么
L.S.C.X都是电磁波波段的划分代号. 最早用于搜索雷达的电磁波波长度为23cm,这一波段被定义为L波段(英语Long的字头),后来这一波段的中心波长度变为22cm. 当波长为10cm的电磁波被使用 ...
- android通过代码获取华为手机的EMUI系统版本号
因为app中用到华为推送,但是华为推送在不同版本上是存在不同问题的,需要单独来处理. 那么最基本的问题是要获取EMUI系统的版本号. 上网翻了很多博客帖子,基本上是在获取root权限下去读取/syst ...
- 【shell编程基础1】shell变量篇
Bash shell bash shell 是bourne shell 的升级版,“bourne again shell”.ubuntu的默认shell. 预备知识 1. "#!" ...
- 对百度WebUploader的二次封装,精简前端代码之图片预览上传(两句代码搞定上传)
前言 本篇文章上一篇: 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传) 此篇是在上面的基础上扩展出来专门上传图片的控件封装. 首先我们看看效果: 正文 使用方式同 ...
- java OJ题目判断输入结束(与C语言的EOF结束等价)
/* * java 作Oj题目是会有输入若干数据的情况,不好判断输入结束符, * 类似于C语言中的EOF符号 * 在这里提供了一种方法 * */ import java.util.Iterator; ...
- html字体问题
正如咱们在上一章中解说的那样,HTML元素使页面规划者能够对文档的构造进行符号.HTML标准列出了浏览器应该怎么显现这些元素的攻略.例如,您能够合理地保证强元素的内容将显现粗体.此外,您能够非常信赖大 ...
- 一个只有99行代码的JS流程框架(二)
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 张镇圳,腾讯Web前端高级工程师,对内部系统前端建设有多年经验,喜欢钻研捣鼓各种前端组件和框架. 导语 前面写 ...
- .net之抽象工厂模式
//抽象工厂 //抽象食物 namespace abstractFactory{ public abstract class food { public abstract void Food(); } ...
- JAVA-Socket通信笔记
JAVA - Socket 从开学到现在 也学了三个月时间的java了,一直在 在 语法和基本使用上周旋,井底之娃一枚. 这两天 有学长指点,花了两天的时间 学习了java多线程和socket的简单使 ...
- Linux五种IO模型性能分析
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步: 所谓同步,就是在发出一个功能调用时, ...