JAVA经验:很有启发(二)

上回讲了Java动态加载机制、classLoader原理和关于jdk和jre三个问题。这次延续着讲一些具体的类库:

  1. 关于集合框架类

   相信学过Java的各位对这个名词并不陌生,对 java.util.*这个package肯定也不陌生。不知道大家查询API的时候怎么去审视或者分析其中的一个package,每个包最重要的两个部 分就是interfaces和classes,接口代表了它能做什么,实现类则代表了它如何去做。关注实现类之前,我们应该先理解清楚它的来源接口,不管 在j2se还是j2ee中,都应该是这样。那么我们先看这三个接口:List、Set、Map。

  也许有些人不太熟悉这三个名字,但相信 大部分人都熟悉ArrayList,LinkedList,TreeSet,HashSet,HashMap, Hashtable等实现类的名字。它们的区别也是满容易理解的,List放可以重复的对象集合,Set放不可重复的对象组合,而Map则放 这样的名值对, Key不可重复,Value可以。这里有几个容易混淆的问题:

  到底Vector和ArrayList,Hashtable和HashMap有什么区别?

  很多面试官喜欢问这个问题,其实更专业一点应该这样问:新集合框架和旧集合框架有哪些区别?新集合框架大家可以在这些包中找since jdk1.2的,之前的如vector和Hashtable都是旧的集合框架包括的类。那么区别是?

  a. 新集合框架的命名更加科学合理。例如List下的ArrayList和LinkedList

  b. 新集合框架下全部都是非线程安全的。建议去jdk里面包含的源代码里面自己去亲自看看vector和ArrayList的区别吧。当然如果是jdk5.0之后的会比较难看一点,因为又加入了泛型的语法,类似c++的template语法。

  那么大家是否想过为什么要从旧集合框架默认全部加锁防止多线程访问更新到新集合框架全部取消锁,默认方式支持多线程?(当然需要的时候可以使用collections的静态方法加锁达到线程安全)

   笔者的观点是任何技术的发展都未必是遵循它们的初衷的,很多重大改变是受到客观环境的影响的。大家知道Java的初衷是为什么而开发的麽?是为嵌入式程 序开发的。记得上一篇讲到classLoader机制麽?那正是为了节约嵌入式开发环境下内存而设计的。而走到今天,Java成了人们心中为互联网诞生的语言。互联网意味着什么?多线程是必然的趋势。客观环境在变,Java技术也随着飞速发展,导致越来越脱离它的初衷。据说Sun公司其实主打的是J2se,结果又是由于客观环境影响,J2se几乎遗忘,留在大家谈论焦点的一直是j2ee。

  技术的细节这里就不多说了,只有用了才能真正理解。解释这些正是为了帮助大家理解正在学的和将要学的任何技术。之后讲j2ee的时候还会再讨论。

  多扯句题外话:几十年前的IT巨人是IBM,Mainframe市场无人可比。微软如何打败IBM?正是由于硬件飞速发展,对个人PC的需求这个客观环境,让微软通过OS称为了第二个巨人。下一个打败微软的呢?Google。 如何做到的?如果微软并不和IBM争大型机,Google借着互联网飞速发展这个客观环境作为决定性因素,避开跟微软争OS,而是走搜索引擎这条路,称为 第3个巨人。那么第4个巨人是谁呢?很多专家预言将在亚洲或者中国出现, Whatever,客观环境变化趋势才是决定大方向的关键。当然笔者也希望会出现在中国,^_^~~ 2. 关于Java设计模式

  身边的很多在看GOF的23种设计模式,似乎学习它无论在学校还是在职场,都成了一种流行风气。我不想列举解释这23种Design Pattern, 我写这些的初衷一直都是谈自己的经历和看法,希望能帮助大家理解。

  首先我觉得设计模式只是对一类问题的一种通用解决办法,只要是面向对象的编程预言都可以用得上这23种。理解它们最好的方法就是亲自去写每一 种,哪怕是一个简单的应用就足够了。如果代码实现也记不住的话,记忆它们对应的UML图会是一个比较好的办法,当然前提是必须了解UML。

  同时最好能利用Java自身的类库帮助记忆,例如比较常用的观察者模式,在java.util.*有现成的Observer接口和 Observable这个实现类,看看源代码相信就足够理解观察者模式了。再比如装饰器模式,大家只要写几个关于java.io.*的程序就可以完全理解 什么是装饰器模式了。有很多人觉得刚入门的时候不该接触设计模式,比如图灵设计丛书系列很出名的那本《Java设计模式》,作者: Steven John Metsker,大部分例子老实说令现在的我也很迷惑。但我仍然不同意入门跟学习设计模式有任何冲突,只是我们需要知道每种模式的概念的和典型的应用,这 样我们在第一次编写 FileOutputStream、BufferedReader、PrintWriter的时候就能感觉到原来设计模式离我们如此之近,而且并不是多么 神秘的东西。

  另外,在学习某些模式的同时,反而更能帮助我们理解java类库的某些特点。例如当你编写原型(Prototype)模式的时候,你必须了解的 是 java.lang.Cloneable这个接口和所有类的基类Object的clone()这个方法。即深copy和浅copy的区别:

  Object.clone()默认实现的是浅copy,也就是复制一份对象拷贝,但如果对象包含其他对象的引用,不会复制引用,所以原对象和拷贝共用那个引用的对象。

  深copy当然就是包括对象的引用都一起复制啦。这样原对象和拷贝对象,都分别拥有一份引用对象。如果要实现深copy就必须首先实现 java.lang.Cloneable接口,然后重写clone()方法。因为在Object中的clone()方法是protected签名的,而 Cloneable接口的作用就是把protected放大到public,这样clone()才能被重写。

  那么又有个问题了?如果引用的对象又引用了其他对象呢?这样一直判断并复制下去,是不是显得很麻烦?曾经有位前辈告诉我的方法是重写clone 方法的时候直接把原对象序列化到磁盘上再反序列化回来,这样不用判断就可以得到一个深copy的结果。如果大家不了解序列化的作法建议看一看 ObjectOutputStream和ObjectInputStream

  归根结底,模式只是思想上的东西,把它当成前人总结的经验其实一点都不为过。鼓励大家动手自己去写,例如代理模式,可以简单的写一个Child 类, Adult类。Child要买任何东西由Adult来代理实现。简单来说就是Adult里的buy()内部实际调用的是Child的buy(),可是暴露 在main函数的却是Adult.buy()。这样一个简单的程序就足够理解代理模式的基本含义了。

时间: 2024-10-12 09:28:06

JAVA经验:很有启发(二)的相关文章

Java I/O流操作(二)---缓冲流[转]

转自:http://blog.csdn.net/johnny901114/article/details/8710403 一.BufferWriter类 IO的缓冲区的存在就是为了提高效率,把要操作的数据放进缓冲区,然后一次性把缓冲区的内容写到目的地,而不是写一次就往目的地写一次. 在这里要注意的是当我们关闭了缓冲区对象实际也关闭了与缓冲区关联的流对象. BufferWriter类 try { FileWriter fw =new FileWriter("test.txt"); //使

Java之GUI编程(二)——布局管理器

在上篇博客Java之GUI编程(一)中我已经对GUI编程的组件和事件做了简单介绍了,现在来看看另外一部分关于组件在各个平台是如何做到仍能保持自己合理的位置大小以及外观的. 已经说了Java是跨平台运行的,但是不同的平台对于点及坐标的定义不完全相同.而且屏幕的解析度分辨率不同也会造成位置的变化,为了确保每个组件的相对位置和大小以及外观,java就设计了布局管理器. 布局管理器是对容器中的元素进行管理,按照一定的规则排放容器里面的元素.它控制了组件的摆放. 布局管理器分类: FlowLayout:浮

JAVA环境下利用solrj二次开发SOlR搜索的环境部署常见错误

问题一:出现控制台坏的响应错误一Bad request 控制台出现错误如下: Bad Request request: http://hostIP:8983/solr/update?wt=javabin&version=1 解决方法: 出现以上错误的原因是,solr服务器上配置的Field和javabean提交的Field不能对应, 导致solr服务器找不到域,拒绝访问. 打开SOLR_HOME下的conf文件夹找到schema.xml文件,在其中添加对应的域. 例如以下代码添加了:title,

java并发包小结(二)

接上一篇 java并发包小结(一):http://blog.csdn.net/aalansehaiyang52/article/details/8877579 Future 接口Future 接口允许表示已经完成的任务.正在执行过程中的任务或者尚未开始执行的任务.通过 Future 接口,可以尝试取消尚未完成的任务,查询任务已经完成还是取消了,以及提取(或等待)任务的结果值.FutureTask 类实现了 Future,并包含一些构造函数,允许将 Runnable 或 Callable(会产生结

JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Fiald,Method,反射Main方法,数组的反射和实践

JAVA进阶之旅(二)--认识Class类,反射的概念,Constructor,Fiald,Method,反射Main方法,数组的反射和实践 我们继续聊JAVA,这次比较有意思,那就是反射了 一.认识Class类 想要反射,你就必须要了解一个类--Class,我们知道,java程序中的各个java类都属于同一事物,我们通常用Classliability描述对吧,反射这个概念从JDK1.2就出来了,历史算是比较悠久了,这个Class可不是关键字哦,这个是一个类,他代表的是一类事物: 我们归根结底就

转载——Java与WCF交互(二):WCF客户端调用Java Web Service

在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttpBinding可行,而NetTcpBinding不可行,具体原因待查.昨晚回去重新测试WCF客户端调用Java Web Service,并将过程公布如下: 其实本不需要做web service,只是原来公开的经典的Web service像(http://soapinterop.java.sun.com/rou

JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917 我们来继续学习多线程 Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock Lock void lock():获取锁 v

java基础巩固系列(二):Integer与int之间的区别

在JDK1.5之后引入了自动装箱(autoboxing)与自动拆箱(unboxing),这让很多对java的初学者感到很疑惑,我刚才也是其中一员. 首先,有一些基本的概念需要了解: 1.Ingeter是int的包装类,int的初值为0,Ingeter的初值为null. 2.Integer是一个类,用Integer声明一个变量是一个对象类型(或者说引用类型):int是基本类型,用int声明的变量是非对象类型,即不能在其上调用方法. 3."=="作用于对象上的时候,其比较的是对象的引用本身

java编程思想总结(二)

java编程思想总结(二) java编程思想总结是一个持续更新的系列,是本人对自己多年工作中使用到java的一个经验性总结,也是温故而知新吧,因为很多基础的东西过了这么多年,平时工作中用不到也会遗忘掉,所以看看书,上上网,查查资料,也算是记录下自己的笔记吧,过一段时间之后再来看看也是蛮不错的,也希望能帮助到正在学习的人们,本系列将要总结一下几点: 面向对象的编程思想 java的基本语法 一些有趣的框架解析 实战项目的整体思路 代码的优化以及性能调优的几种方案 整体项目的规划和视角 其它遗漏的东西

Java并发编程系列之二十五:线程池

线程池简介 在之前介绍Executor框架的文章中对线程池有一个初步的认识,实际上线程池这种设计思想在Java中很普遍,比如JVM中常量池,以及Web开发使用到的数据库连接池.这些池本质上还是Java中的对象池,因为池中存放的都是Java对象.回到线程池,几乎所有需要异步或者执行并发任务的程序都可以使用到线程池.使用线程池带来的好处主要包括以下几个方面: 一,提高资源利用率.由于线程池中的线程使可以重复利用的,所以达到了循环利用的目的 二,提高响应速度.由于线程的创建也是需要开销的,如果请求到来