??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲日韩亚洲另类激情文学,国产偷国产偷亚洲高清日韩,亚洲AV成人精品日韩一区http://www.tkk7.com/ltc603/category/6947.html<font size="3">学无止境</font> <br> <script type="text/javascript" src="http://wujunlove.googlepages.com/bigstaticeyes.js"></script>zh-cnTue, 10 Apr 2007 00:13:48 GMTTue, 10 Apr 2007 00:13:48 GMT60什么是U程局部变量(thread-local variableQ?L使用U程: 不共享有时是最好的http://www.tkk7.com/ltc603/archive/2007/04/09/109492.html阿成阿成Mon, 09 Apr 2007 12:52:00 GMThttp://www.tkk7.com/ltc603/archive/2007/04/09/109492.htmlhttp://www.tkk7.com/ltc603/comments/109492.htmlhttp://www.tkk7.com/ltc603/archive/2007/04/09/109492.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/109492.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/109492.html cL悄悄地出现在 Java q_版本 1.2 中的。虽然支持线E局部变量早是许多U程工具Q例?Posix 工具Q的一部分Q但 Java Threads API 的最初设计却没有q项有用的功能。而且Q最初的实现也相当低效。由于这些原因, 极少受到xQ但对简化线E安全ƈ发程序的开发来_它却是很方便的。在 L使用U程的第 3 部分QJava 软gN Brian Goetz 研究? q提供了一些用技巧?

参加 Brian ?多线E?Java ~程讨论论坛以获得您工程中的U程和ƈ发问题的帮助?

~写U程安全cL困难的。它不但要求仔细分析在什么条件可以对变量q行dQ而且要求仔细分析其它c能如何使用某个cR?有时Q要在不影响cȝ功能、易用性或性能的情况下使类成ؓU程安全的是很困隄。有些类保留从一个方法调用到下一个方法调用的状态信息,要在实践中ɘq样的类成ؓU程安全的是困难的?/p>

理非线E安全类的用比试图使类成ؓU程安全的要更容易些。非U程安全c通常可以安全地在多线E程序中使用Q只要您能确保一个线E所用的cȝ实例不被其它U程使用。例如,JDBC cL非线E安全的 ?两个U程不能在小_度U上安全地共享一? ?但如果每个线E都有它自己? Q那么多个线E就可以同时安全地进行数据库操作?

不? 为每个线E维护一个单独的 JDBC q接Q或M其它对象Q当然是可能的;Thread API l了我们把对象和U程联系h所需的所有工兗?ThreadLocal 则我们能更Ҏ地把U程和它的每U程Qper-threadQ数据成功地联系h?

什么是U程局部变量(thread-local variableQ?

U程局部变?/em>高效Cؓ每个使用它的U程提供单独的线E局部变量值的副本。每个线E只能看C自己相联pȝ|而不知道别的U程可能正在使用或修改它们自q副本。一些编译器Q例?Microsoft Visual C++ ~译器或 IBM XL FORTRAN ~译器)用存储类别修饰符Q像 ? Q把对线E局部变量的支持集成C其语a中。Java ~译器对U程局部变量不提供特别的语a支持Q相反地Q它? cd现这些支持, cM有这个类的特别支持?

因ؓU程局部变量是通过一个类来实现的Q而不是作?Java 语言本n的一部分Q所?Java 语言U程局部变量的使用语法比内建线E局部变量语a的用语法要W拙一些。要创徏一个线E局部变量,请实例化c? 的一个对象? cȝ行ؓ? 中的各种 cȝ行ؓ很相| cd当存储或索一个值时的间接句柄。清?1 昄? 接口?


清单 1. ThreadLocal 接口

            public class ThreadLocal {
            public Object get();
            public void set(Object newValue);
            public Object initialValue();
            }
            

讉K器检索变量的当前U程的| 讉K器修改当前线E的倹{? Ҏ是可选的Q如果线E未使用q某个变量,那么您可以用q个Ҏ来设|这个变量的初始|它允许gq初始化。用一个示例实现来说明 ThreadLocal 的工作方式是最好的Ҏ。清?2 昄? 的一个实现方式。它不是一个特别好的实玎ͼ虽然它与最初实现非常相|Q所以很可能性能不佳Q但它清楚地说明?ThreadLocal 的工作方式?


清单 2. ThreadLocal 的糟p实?/font>

            public class ThreadLocal {
            private Map values = Collections.synchronizedMap(new HashMap());
            public Object get() {
            Thread curThread = Thread.currentThread();
            Object o = values.get(curThread);
            if (o == null && !values.containsKey(curThread)) {
            o = initialValue();
            values.put(curThread, o);
            }
            return o;
            }
            public void set(Object newValue) {
            values.put(Thread.currentThread(), newValue);
            }
            public Object initialValue() {
            return null;
            }
            }
            

q个实现的性能不会很好Q因为每? ? 操作都需? 映射表上的同步,而且如果多个U程同时讉K同一? Q那么将发生争用。此外,q个实现也是不切实际的,因ؓ? 对象? 映射表中的关键字导致无法在U程退出后? q行垃圾回收Q而且也无法对ȝE的 的特定于U程的D行垃圑֛收?





回页?/u>


?ThreadLocal 实现每线E?Singleton

U程局部变量常被用来描l有状?#8220;单子”QSingletonQ?或线E安全的׃n对象Q或者是通过把不安全的整个变量封装进 Q或者是通过把对象的特定于线E的状态封装进 。例如,在与数据库有紧密联系的应用程序中Q程序的很多Ҏ可能都需要访问数据库。在pȝ的每个方法中都包含一? 作ؓ参数是不方便???#8220;单子”来访问连接可能是一个虽然更_糙Q但却方便得多的技术。然而,多个U程不能安全地共享一?JDBC 。如清单 3 所C,通过使用“单子”中的 Q我们就能让我们的程序中的Q何类Ҏ地获取每U程 的一个引用。这P我们可以认ؓ 允许我们创徏 每线E单?/em>?


清单 3. 把一?JDBC q接存储C个每U程 Singleton ?/font>

            public class ConnectionDispenser {
            private static class ThreadLocalConnection extends ThreadLocal {
            public Object initialValue() {
            return DriverManager.getConnection(ConfigurationSingleton.getDbUrl());
            }
            }
            private ThreadLocalConnection conn = new ThreadLocalConnection();
            public static Connection getConnection() {
            return (Connection) conn.get();
            }
            }
            

M创徏的花Ҏ使用的花费相Ҏ贵些的有状态或非线E安全的对象Q例?JDBC 或正则表辑ּ匚w器,都是可以使用每线E单子(singletonQ技术的好地斏V当Ӟ在类DL地方Q您可以使用其它技术,例如用池Q来安全地管理共享访问。然而,从可伸羃性角度看Q即使是用池也存在一些潜在缺陗因为池实现必须使用同步Q以l护池数据结构的完整性,如果所有线E用同一个池Q那么在有很多线E频J地Ҏq行讉K的系l中Q程序性能因争用而降低?





回页?/u>


?ThreadLocal 化调试日志纪?/font>

其它适合使用 但用池却不能成ؓ很好的替代技术的应用E序包括存储或篏U每U程上下文信息以备稍后检索之用这L应用E序。例如,假设您想创徏一个用于管理多U程应用E序调试信息的工兗您可以用如清单 4 所C的 cM为线E局部容器来累积调试信息。在一个工作单元的开_您清I容器,而当一个错误出现时Q您查询该容器以索这个工作单元迄今ؓ止生成的所有调试信息?


清单 4. ?ThreadLocal 理每线E调试日?/font>

            public class DebugLogger {
            private static class ThreadLocalList extends ThreadLocal {
            public Object initialValue() {
            return new ArrayList();
            }
            public List getList() {
            return (List) super.get();
            }
            }
            private ThreadLocalList list = new ThreadLocalList();
            private static String[] stringArray = new String[0];
            public void clear() {
            list.getList().clear();
            }
            public void put(String text) {
            list.getList().add(text);
            }
            public String[] get() {
            return list.getList().toArray(stringArray);
            }
            }
            

在您的代码中Q您可以调用 来保存您的程序正在做什么的信息Q而且Q稍后如果有必要Q例如发生了一个错误)Q您能够Ҏ地检索与某个特定U程相关的调试信息?与简单地把所有信息{储到一个日志文Ӟ然后努力扑և哪个日志记录来自哪个U程Q还要担心线E争用日志纪录对象)相比Q这U技术简便得多,也有效得多?

在基?servlet 的应用程序或工作单元是一个整体请求的M多线E应用程序服务器中也是很有用的,因ؓ在处理请求的整个q程中将要用到单个线E。您可以通过前面讲述的每U程单子技术用 变量来存储各U每hQper-requestQ上下文信息?





回页?/u>


ThreadLocal 的线E安全性稍差的堂兄弟,InheritableThreadLocal

ThreadLocal cL一个亲戚,InheritableThreadLocalQ它以相似的方式工作Q但适用于种cd全不同的应用E序。创Z个线E时如果保存了所? 对象的|那么q些g自动传递给子线E。如果一个子U程调用 ? Q那么它与它的父线E看到同一个对象。ؓ保护U程安全性,您应该只对不可变对象Q一旦创建,其状态就永远不会被改变的对象Q? Q因为对象被多个U程׃n? 很合适用于把数据从父U程传到子线E,例如用户标识Quser idQ或事务标识Qtransaction idQ,但不能是有状态对象,例如 JDBC ?





回页?/u>


ThreadLocal 的性能

虽然U程局部变量早已赫赫有名ƈ被包?Posix 规范在内的很多线E框架支持,但最初的 Java U程设计中却省略了它Q只是在 Java q_的版?1.2 中才d上去。在很多斚wQ? 仍在发展之中Q在版本 1.3 中它被重写,版本 1.4 中又重写了一ơ,两次都专门是Z性能问题?

?JDK 1.2 中, 的实现方式与清单 2 中的方式非常怼Q除了用同步 代替 来存?values 之外。(以一些额外的性能开销ZP使用 WeakHashMap 解决了无法对 Thread 对象q行垃圾回收的问题。)不用_ 的性能是相当差的?

Java q_版本 1.3 提供? 版本已经量更好了;它不使用M同步Q从而不存在可׾~性问题,而且它也不用弱引用。相反地Qh们通过l? d一个实例变量(该变量用于保存当前线E的从线E局部变量到它的值的映射? Q来修改 cM支持 。因为检索或讄一个线E局部变量的q程不涉及对可能被另一个线E读写的数据的读写操作,所以您可以不用M同步实? ? 。而且Q因为每U程值的引用被存储在自已? 对象中,所以当? q行垃圾回收Ӟ也能对该 的每U程D行垃圑֛收?

不幸的是Q即使有了这些改q,Java 1.3 中的 的性能仍然出奇地慢。据我的_略量Q在双处理器 Linux pȝ上的 Sun 1.3 JDK 中进? 操作Q所耗费的时间大U是无争用同步的两倍。性能q么差的原因? Ҏ的花贚w常大Q占? q行旉的三分之二还多。虽然有q些~点QJDK 1.3 仍然比争用同步快得多Q所以如果在M存在严重争用的地方(可能是有非常多的U程Q或者同步块被频J地执行Q或者同步块很大Q, 可能仍然要高效得多?

?Java q_的最新版本,即版?1.4b2 中, ? 的性能都有了很大提高。有了这些提高, 应该比其它技术,如用池,更快。由于它比其它技术更单,也更不易出错Qh们最l将发现它是避免U程间出C希望的交互的有效途径?





回页?/u>


ThreadLocal 的好?/font>

能带来很多好处。它常常是把有状态类描绘成线E安全的Q或者封装非U程安全cM使它们能够在多线E环境中安全C用的最Ҏ的方式。? 使我们可以绕qؓ实现U程安全而对何时需要同步进行判断的复杂q程Q而且因ؓ它不需要Q何同步,所以也改善了可伸羃性。除单之外,? 存储每线E单子或每线E上下文信息在归方面还有一个颇有h值好??通过使用 Q存储在 中的对象都是 ?/em>被线E共享的是清晰的Q从而简化了判断一个类是否U程安全的工作?

我希望您从这个系列中得到了乐,也学C知识Q我也鼓励您到我?讨论论坛中来深入研究多线E问题?



阿成 2007-04-09 20:52 发表评论
]]>
Java虚拟机的深入研究--?/title><link>http://www.tkk7.com/ltc603/archive/2006/10/15/75267.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Sun, 15 Oct 2006 07:39:00 GMT</pubDate><guid>http://www.tkk7.com/ltc603/archive/2006/10/15/75267.html</guid><wfw:comment>http://www.tkk7.com/ltc603/comments/75267.html</wfw:comment><comments>http://www.tkk7.com/ltc603/archive/2006/10/15/75267.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/ltc603/comments/commentRss/75267.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/ltc603/services/trackbacks/75267.html</trackback:ping><description><![CDATA[ <div align="left"> <p class="title" align="center">Java虚拟机的深入研究</p> <p align="center">作者:刘学?</p> <p> <b>1  Java技术与Java虚拟?/b> </p> <p class="normal">说vJavaQh们首先想到的是Java~程语言Q然而事实上QJava是一U技术,它由四方面组? Java~程语言、JavacL件格式、Java虚拟机和Java应用E序接口(Java API)。它们的关系如下图所C:</p> <p align="center"> <img height="397" alt="" src="http://gceclub.sun.com.cn/staticcontent/html/2004-04-09/jvm01.gif" width="529" border="0" /> </p> <p align="center">?  Java四个斚w的关p?/p> <p class="normal">q行期环境代表着Javaq_Q开发h员编写Java代码(.java文g)Q然后将之编译成字节?.class文g)。最后字节码被装入内存,一旦字节码q入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的{换成机器码执行。从上图也可以看出Javaq_由Java虚拟机和Java应用E序接口搭徏QJava语言则是q入q个q_的通道Q用Java语言~写q编译的E序可以q行在这个^C。这个^台的l构如下图所C:</p> <p align="center"> <img height="251" alt="" src="http://gceclub.sun.com.cn/staticcontent/html/2004-04-09/jvm02.gif" width="609" border="0" /> </p> <p class="normal">在Javaq_的结构中, 可以看出QJava虚拟?JVM) 处在核心的位|,是程序与底层操作pȝ和硬件无关的关键。它的下ҎUL接口Q移植接口由两部分组成:适配器和Java操作pȝ, 其中依赖于^台的部分UCؓ适配器;JVM 通过UL接口在具体的q_和操作系l上实现Q在JVM 的上ҎJava的基本类库和扩展cd以及它们的APIQ?利用Java API~写的应用程?application) 和小E序(Java applet) 可以在Q何Javaq_上运行而无需考虑底层q_, 是因ؓ有Java虚拟?JVM)实现了程序与操作pȝ的分,从而实CJava 的^台无x? </p> <p class="normal">那么到底什么是Java虚拟?JVM)呢?通常我们谈论JVMӞ我们的意思可能是Q? </p> <ol> <li>对JVM规范的的比较抽象的说明; </li> <li>对JVM的具体实玎ͼ </li> <li>在程序运行期间所生成的一个JVM实例?</li> </ol> <p class="normal">对JVM规范的的抽象说明是一些概늚集合Q它们已l在书《The Java Virtual Machine Specification》(《Java虚拟范》)中被详细地描qCQ对JVM的具体实现要么是软gQ要么是软g和硬件的l合Q它已经被许多生产厂商所实现Qƈ存在于多U^C上;q行JavaE序的Q务由JVM的运行期实例单个承担。在本文中我们所讨论的Java虚拟?JVM)主要针对W三U情况而言。它可以被看成一个想象中的机器,在实际的计算Z通过软g模拟来实玎ͼ有自己想象中的硬Ӟ如处理器、堆栈、寄存器{,q有自己相应的指令系l?/p> <p class="normal">JVM在它的生存周期中有一个明的dQ那是q行JavaE序Q因此当JavaE序启动的时候,׃生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体pȝ构和它的q行q程q两个方面来对它q行比较深入的研I? </p> <p> <b>2  Java虚拟机的体系l构</b> </p> <p class="normal">刚才已经提到QJVM可以׃同的厂商来实现。由于厂商的不同必然DJVM在实C的一些不同,然而JVMq是可以实现跨^台的Ҏ,q就要归功于设计JVM时的体系l构了?/p> <p class="normal">我们知道Q一个JVM实例的行Z光是它自q事,q涉及到它的子系l、存储区域、数据类型和指oq些部分Q它们描qCJVM的一个抽象的内部体系l构Q其目的不光规定实现JVM时它内部的体pȝ构,更重要的是提供了一U方式,用于严格定义实现时的外部行ؓ。每个JVM都有两种机制Q一个是装蝲h合适名U的c?cL是接?Q叫做类装蝲子系l;另外的一个负责执行包含在已装载的cL接口中的指oQ叫做运行引擎。每个JVM又包括方法区、堆、Java栈、程序计数器和本地方法栈q五个部分,q几个部分和c装载机制与q行引擎机制一L成的体系l构图ؓQ?/p> <p align="center"> <img height="299" alt="" src="http://gceclub.sun.com.cn/staticcontent/html/2004-04-09/jvm03.gif" width="589" border="0" /> </p> <p align="center">?  JVM的体pȝ?/p> <p class="normal">JVM的每个实例都有一个它自己的方法域和一个堆Q运行于JVM内的所有的U程都共享这些区域;当虚拟机装蝲cL件的时候,它解析其中的二进制数据所包含的类信息Qƈ把它们放到方法域中;当程序运行的时候,JVM把程序初始化的所有对象置于堆上;而每个线E创建的时候,都会拥有自己的程序计数器和Java栈,其中E序计数器中的值指向下一条即被执行的指令,U程的Java栈则存储U程调用JavaҎ的状态;本地Ҏ调用的状态被存储在本地方法栈Q该Ҏ栈依赖于具体的实现?/p> <p class="normal">下面分别对这几个部分q行说明?/p> <p class="normal">执行引擎处于JVM的核心位|,在Java虚拟范中Q它的行为是由指令集所军_的。尽对于每条指令,规范很详l地说明了当JVM执行字节码遇到指令时Q它的实现应该做什么,但对于怎么做却a之甚。Java虚拟机支持大U?48个字节码。每个字节码执行一U基本的CPUq算,例如,把一个整数加到寄存器,子程序{Uȝ。Java指o集相当于JavaE序的汇~语a?/p> <p class="normal">Java指o集中的指令包含一个单字节的操作符,用于指定要执行的操作,q有0个或多个操作?提供操作所需的参数或数据。许多指令没有操作数,仅由一个单字节的操作符构成?/p> <pre>虚拟机的内层循环的执行过E如? do{ 取一个操作符字节; Ҏ操作W的值执行一个动? }while(E序未结? </pre> <p class="normal">׃指opȝ的简单?使得虚拟机执行的q程十分?从而有利于提高执行的效率。指令中操作数的数量和大是由操作符军_的。如果操作数比一个字节大,那么它存储的序是高位字节优先。例?一?6位的参数存放时占用两个字?其gؓ: </p> <p class="normal">W一个字?256+W二个字节字节码? </p> <p class="normal">指o一般只是字节对齐的。指令tableswitch和lookup是例?在这两条指o内部要求强制?字节边界寚w? </p> <p class="normal">对于本地Ҏ接口Q实现JVMq不要求一定要有它的支持,甚至可以完全没有。Sun公司实现Java本地接口(JNI)是出于可UL性的考虑Q当然我们也可以设计出其它的本地接口来代替Sun公司的JNI。但是这些设计与实现是比较复杂的事情Q需要确保垃圑֛收器不会那些正在被本地Ҏ调用的对象释放掉? </p> <p class="normal">Java的堆是一个运行时数据?cȝ实例(对象)从中分配I间Q它的管理是由垃圑֛收来负责?不给E序员显式释攑֯象的能力。Java不规定具体用的垃圾回收法,可以Ҏpȝ的需求用各U各L法? </p> <p class="normal">JavaҎZ传统语言中的~译后代码或是Unixq程中的正文D늱伹{它保存Ҏ代码(~译后的java代码)和符可。在当前的Java实现?Ҏ代码不包括在垃圾回收堆中,但计划在来的版本中实现。每个类文g包含了一个JavacL一个Java界面的编译后的代码。可以说cL件是Java语言的执行代码文件。ؓ了保证类文g的^台无x?Java虚拟范中对类文g的格式也作了详细的说明。其具体l节请参考Sun公司的Java虚拟范? </p> <p class="normal">Java虚拟机的寄存器用于保存机器的q行状?与微处理器中的某些专用寄存器cM。Java虚拟机的寄存器有四种: </p> <ol> <li>pc: JavaE序计数器; </li> <li>optop: 指向操作数栈端的指针; </li> <li>frame: 指向当前执行Ҏ的执行环境的指针Q? </li> <li>vars: 指向当前执行Ҏ的局部变量区W一个变量的指针?</li> </ol> <p class="normal">在上qCpȝ构图中,我们所说的是第一U,即程序计数器Q每个线E一旦被创徏拥有了自己的程序计数器。当U程执行JavaҎ的时候,它包含该U程正在被执行的指o的地址。但是若U程执行的是一个本地的ҎQ那么程序计数器的值就不会被定义? </p> <p class="normal">Java虚拟机的栈有三个区域:局部变量区、运行环境区、操作数区?/p> <p> <b>局部变量区</b> </p> <p class="normal">每个JavaҎ使用一个固定大的局部变量集。它们按照与vars寄存器的字偏U量来寻址。局部变量都?2位的。长整数和双_ֺ点数占据了两个局部变量的I间,却按照第一个局部变量的索引来寻址?例如,一个具有烦引n的局部变?如果是一个双_ֺ点?那么它实际占据了索引n和n+1所代表的存储空?虚拟范ƈ不要求在局部变量中?4位的值是64位对齐的。虚拟机提供了把局部变量中的D载到操作数栈的指?也提供了把操作数栈中的值写入局部变量的指o?/p> <p> <b>q行环境?/b> </p> <p class="normal">在运行环境中包含的信息用于动态链?正常的方法返回以及异常捕捉? </p> <p class="normal"> <b>动态链?/b> </p> <p class="normal">q行环境包括Ҏ向当前类和当前方法的解释器符可的指?用于支持Ҏ代码的动态链接。方法的class文g代码在引用要调用的方法和要访问的变量时用符受动态链接把W号形式的方法调用翻译成实际Ҏ调用,装蝲必要的类以解释还没有定义的符?q把变量讉K译成与q些变量q行时的存储l构相应的偏Ud址。动态链接方法和变量使得Ҏ中用的其它cȝ变化不会影响到本E序的代码? </p> <p class="normal"> <b>正常的方法返?/b> </p> <p class="normal">如果当前Ҏ正常地结束了,在执行了一条具有正类型的q回指o?调用的方法会得到一个返回倹{执行环境在正常q回的情况下用于恢复调用者的寄存?q把调用者的E序计数器增加一个恰当的数?以蟩q已执行q的Ҏ调用指o,然后在调用者的执行环境中l执行下厅R? </p> <p class="normal"> <b>异常捕捉</b> </p> <p class="normal">异常情况在Java中被UCError(错误)或Exception(异常),是Throwablecȝ子类,在程序中的原因是:①动态链接错,如无法找到所需的class文g。②q行旉,如对一个空指针的引用。程序用了throw语句? </p> <p class="normal">当异常发生时,Java虚拟机采取如下措? </p> <ul> <li>查与当前Ҏ相联pȝcatch子句表。每个catch子句包含其有效指令范?能够处理的异常类?以及处理异常的代码块地址? </li> <li>与异常相匚w的catch子句应该W合下面的条?造成异常的指令在其指令范围之?发生的异常类型是其能处理的异常类型的子类型。如果找C匚w的catch子句,那么pȝ转移到指定的异常处理块处执行;如果没有扑ֈ异常处理?重复L匚w的catch子句的过E?直到当前Ҏ的所有嵌套的catch子句都被查过? </li> <li>׃虚拟ZW一个匹配的catch子句处l执?所以catch子句表中的顺序是很重要的。因为Java代码是结构化?因此d以把某个Ҏ的所有的异常处理器都按序排列C个表?对Q意可能的E序计数器的?都可以用U性的序扑ֈ合适的异常处理?以处理在该程序计数器g发生的异常情c? </li> <li>如果找不到匹配的catch子句,那么当前Ҏ得到一?未截获异?的结果ƈq回到当前方法的调用?好像异常刚刚在其调用者中发生一栗如果在调用者中仍然没有扑ֈ相应的异常处理块,那么q种错误被传播下去。如果错误被传播到最层,那么pȝ调用一个缺省的异常处理块?</li> </ul> <p> <b>操作数栈?/b> </p> <p class="normal">机器指o只从操作数栈中取操作?对它们进行操?q把l果q回到栈中。选择栈结构的原因?在只有少量寄存器或非通用寄存器的机器(如Intel486)?也能够高效地模拟虚拟机的行ؓ。操作数栈是32位的。它用于l方法传递参?q从Ҏ接收l果,也用于支持操作的参数,q保存操作的l果。例?iadd指o两个整数相加。相加的两个整数应该是操作数栈顶的两个字。这两个字是由先前的指o压进堆栈的。这两个整数从堆栈弹出、相?q把l果压回到操作数栈中? </p> <p class="normal">每个原始数据cd都有专门的指令对它们q行必须的操作。每个操作数在栈中需要一个存储位|?除了long和double?它们需要两个位|。操作数只能被适用于其cd的操作符所操作。例?压入两个intcd的数,如果把它们当作是一个longcd的数则是非法的。在Sun的虚拟机实现?q个限制由字节码验证器强制实行。但?有少数操?操作Wdupe和swap),用于对运行时数据行操作时是不考虑cd的? </p> <p class="normal">本地Ҏ栈,当一个线E调用本地方法时Q它׃再受到虚拟机关于l构和安全限制方面的U束Q它既可以访问虚拟机的运行期数据区,也可以用本地处理器以及Mcd的栈。例如,本地栈是一个C语言的栈Q那么当CE序调用C函数Ӟ函数的参C某种序被压入栈Q结果则q回l调用函数。在实现Java虚拟机时Q本地方法接口用的是C语言的模型栈Q那么它的本地方法栈的调度与使用则完全与C语言的栈相同?/p> <p> <b>3  Java虚拟机的q行q程</b> </p> <p class="normal">上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过E?/p> <p class="normal">虚拟机通过调用某个指定cȝҎmain启动Q传递给main一个字W串数组参数Q指定的类被装载,同时链接该类所使用的其它的cdQƈ且初始化它们。例如对于程序:</p> <pre>class HelloApp { public static void main(String[] args) { System.out.println("Hello World!"); for (int i = 0; i < args.length; i++ ) { System.out.println(args[i]); } } } </pre> <p class="normal">~译后在命o行模式下键入Q?java HelloApp run virtual machine </p> <p class="normal">通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字W串"run"?virtual"?machine"的数l。现在我们略q虚拟机在执行HelloApp时可能采取的步骤? </p> <p class="normal">开始试图执行类HelloApp的mainҎQ发现该cdƈ没有被装载,也就是说虚拟机当前不包含该类的二q制代表Q于是虚拟机使用ClassLoader试图Lq样的二q制代表。如果这个进E失败,则抛Z个异常。类被装载后同时在mainҎ被调用之前,必须对类HelloApp与其它类型进行链接然后初始化。链接包含三个阶D:验,准备和解析。检验检查被装蝲的主cȝW号和语义,准备则创建类或接口的静态域以及把这些域初始化ؓ标准的默认|解析负责查主cd其它cL接口的符号引用,在这一步它是可选的。类的初始化是对cM声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。整个过E如下:</p> <p align="center"> <img height="610" alt="" src="http://gceclub.sun.com.cn/staticcontent/html/2004-04-09/jvm04.gif" width="702" border="0" /> </p> <p align="center">?Q虚拟机的运行过E?/p> <p> <b>4  l束?/b> </p> <p class="normal">本文通过对JVM的体pȝ构的深入研究以及一个JavaE序执行时虚拟机的运行过E的详细分析Q意在剖析清楚Java虚拟机的机理?/p> </div> <img src ="http://www.tkk7.com/ltc603/aggbug/75267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/ltc603/" target="_blank">阿成</a> 2006-10-15 15:39 <a href="http://www.tkk7.com/ltc603/archive/2006/10/15/75267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OOD原则QSRP、OCP以及LSPhttp://www.tkk7.com/ltc603/archive/2006/09/06/68123.html阿成阿成Wed, 06 Sep 2006 12:35:00 GMThttp://www.tkk7.com/ltc603/archive/2006/09/06/68123.htmlhttp://www.tkk7.com/ltc603/comments/68123.htmlhttp://www.tkk7.com/ltc603/archive/2006/09/06/68123.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/68123.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/68123.html
单一职责原则QSRP : Single Response Principle)

׃个类而言Q应该仅有一个引起它变化的原因?br />在这里,职责的定义是Q?“变化的原因”?/font>

对于何时遵@SRP有以下的考虑Q?br />1.如果应用E序的变化会影响到类中某一U职责,那么应该将它与另一U职责分开Q这样做可以避免客户应用E序和类中的q两职责耦合在一赗?br />2.如果应用E序的变化L会导致两个职责同时变化,那么׃必要分离它们。实际上Q分d们会引v不必要的复杂性?br />
从上可以得知Q变化的轴线仅当变化实际发生时才h真正的意义。如果没有征兆,那么d用SRPQ或者Q何其它原则都是不明智?br />
实际应用Q持久化QPersistenceQ?/strong>
实际开发中Q考虑C务规则是会频J改变的Q而持久化的方式却不会如此频繁的变化,q且变化的原因也是完全不同的。如果把业务规则和持久化方式l定CP׃Z后的开发、维护造成ȝ。运用分层(layerQ架构模式或者TDD开发方式可以很早分这两个职责Q特D情况下Q还可以使用FACADE或者PROXY模式对设计进行重构,分离q两个职责?br />
开闭原则(OCP : The Open-Close Principle)

描述QY件实体(cR模型、函数等{)应该是可以扩展的Q但是不可修攏V?br />
遵@开闭原则设计出的模块具有两个主要的特征。它们是Q?br />1. “对于扩展是开攄”(Open for extensionQ?br />   q意味着模块的行为是可以扩展的。当应用的需要改变时Q我们可以对模块q行扩展Q其具有满那些改变的新行为。换句话_我们可以改变模块的功能?br />2. “对于更Ҏ闭的”(Closed for modificationQ?br />   Ҏ块行行扩展时Q不必改动模块的源代码或者二q制代码。模块的二进制可执行版本Q无论是可链接的库、DLL或者Java?jar文gQ都无需改动?br />
对于OCPQ关键的?抽象
模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,所以它对于更改可以是关闭的。同Ӟ通过从这个抽象体zQ也可以扩展此模块的行ؓ?br />
在许多方面,OCP都是面向对象设计的核心所在。但实际应用中,滥用OCP原则也是错误的。正的做法是应该仅仅对E序中呈现出频繁变化的那些部分做出抽象。拒l不成熟的抽象和抽象本n一样重要?/div>

Liskov替换原则QLSPQ?/font>

描述Q子cdQsubtypeQ必能够替换掉它们的基cdQbase typeQ?br />
此原则是Barbara Liskov首次?988q写下的。所以就叫做Liskov替换原则。她如此写到Q?br />“这里需要如下替换性质Q若Ҏ个类型S的对象o1Q都存在一个类型T的对象o2Q得在所有针对T~写的程序P中,用o1替换o2后,E序P行ؓ功能不变Q则S是T的子cd?br />
LSP然我们得Z个非帔R要的l论Q一个模型,如果孤立的看Qƈ不具有真正意义上的有效性。模型的有效性只能通过它的客户E序来表现?br />
在考虑一个特定设计是否恰当时Q不能完全孤立的来看q个解决Ҏ。必要Ҏ该设计的使用者所做出的合理假设来审视它?br />
有谁知道设计的用者会做出什么样的合理假讑֑Q大多数q样的假N很难预测。事实上Q如果试囑֎预测所有这些假设,我们所得到的系l很可能会充满不必要的复杂性的臭味。因此,像所有其它原则一样了Q通常最好的办法是只预那些最明显的对于LSP的违反情况,而推q所有其它的预测Q直到出现相关的脆弱性的臭味Ӟ才去处理它们?br />
IS-A是关于行为的?/font>
LSP清晰的指出,OOD中ISQA关系是就行ؓ方式而言的,行ؓ方式是可以进行合理假讄Q是客户E序所依赖的?br />
Z契约设计
Z契约设计QDBCQDesign By ContractQ。用DBCQ类的编写者能够显式的规定针对该类的契U。客户代码的~写者可以通过该契U获悉可以依赖的行ؓ方式。契U是通过为每个方法声明的前置条gQpreconditions)和后|条Ӟpostconditions)来指定的。要使一个方法得以执行,前置条g必须要ؓ真。执行完毕后Q该Ҏ要保证后|条件ؓ真?br />
在单元测试中指定契约
也可以通过~写单元试的方式来指定契约。客户代码编写者会L看这些单元测试,q样他们可以知道对于要使用的类Q应该做什么合理的假设?br />
启发式规则和习惯用法

1.zcM的退化函?br />  在基cM实现了f()ҎQ在zcM的函数f()是退化的Q派生类中的退化函数ƈ不总表CZؓq反LSPQ但是当存在q种情况Ӟq是值得注意一下的?br />2.从派生类中抛出异?br />  在派生类的方法中d了其基类不会抛出的异常。如果基cȝ使用者不期望q些异常Q那么把它们d到派生类的方法中׃D不可替换性。此时要遵@LSPQ要么就必须改变使用者的期望Q要么派生类׃应该抛出q些异常?br />
ȝQOCP是OOD中很多原则的核心。如果这个原则应用的有效Q应用程序就会具有更多的可维护性、可重用性以及健壮性。LSP是OCP成ؓ可能的主要原则之一。正是子cd的可替换性才使得使用基类cd的模块在无需修改的情况下可以扩展。这U可替换性必L开发h员可以隐式依赖的。因此,如果没有昑ּ的强制基cȝ型的契约Q那么代码就必须良好的ƈ且明昄表达一炏V?br />      术语IS-A的含义过于广泛以至于不能作ؓ子类型的定义。子cd的正定义是“可替换性”,q里的可替换性可以通过昑ּ或者隐式的契约来定义?/div>


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=749737

相关文章Q?/h3>



阿成 2006-09-06 20:35 发表评论
]]>一些java术语 http://www.tkk7.com/ltc603/archive/2006/09/05/67741.html阿成阿成Tue, 05 Sep 2006 02:11:00 GMThttp://www.tkk7.com/ltc603/archive/2006/09/05/67741.htmlhttp://www.tkk7.com/ltc603/comments/67741.htmlhttp://www.tkk7.com/ltc603/archive/2006/09/05/67741.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/67741.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/67741.html
Abstract class 抽象c?抽象cL不允许实例化的类Q因此一般它需要被q行扩展l承?

  Abstract method 抽象Ҏ:抽象Ҏ即不包含M功能代码的方法?

  Access modifier 讉K控制修饰W?讉K控制修饰W用来修饰Java中类、以及类的方法和变量的访问控制属性?

  Anonymous class 匿名c?当你需要创建和使用一个类Q而又不需要给出它的名?

  Anonymous inner classes 匿名内部c?匿名内部cL没有cd的局部内部类?

  API 应用E序接口:提供特定功能的一l相关的cdҎ的集合?

  Array 数组:存储一个或者多个相同数据类型的数据l构Q用下标来讉K?br />
  Automatic variables 自动变量:也称为方法局部变量method local variablesQ声明在Ҏ体中的变?

  AWT抽象H口工具?一个独立的APIq_提供用户界面功能?

  Base class 基类:卌扩展l承的类?

  Blocked state d状?当一个线E等待资源时卛_于阻塞状态。阻塞状态不使用处理器资?

  Call stack 调用堆栈:调用堆栈是一个方法列表,按调用顺序保存所有在q行期被调用的方法?

  Casting cd转换 :即一个类型到另一个类型的转换

  char 字符:容纳单字W的一U基本数据类型?

  Child class 子类:见承类Derived class

  Class c?面向对象中的最基本、最重要的定义类型?

  Class members cL?定义在类一U的变量Q包括实例变量和静态变量?

  Class methods cL?cL法通常是指的静态方?br />
  Class variable cd?见静态变量Static variable

  Collection 容器c?容器cd以看作是一U可以储存其他对象的对象

  Collection interface 容器cL?容器cL口定义了一个对所有容器类的公共接口?

  Collections framework 容器cL?接口、实现和法三个元素构成了容器类的架构?

  Constructor 构造函?在对象创建或者实例化时候被调用的方法?br />
  Containers容器:容器是一U特D的lgQ它可以容纳其他lg?

  Declaration 声明:声明x在源文g中描q类、接口、方法、包或者变量的语法?

  Derived class l承c?l承cL扩展l承某个cȝcR?

  Encapsulation 装?装性体C面向对象E序设计的一个特?br />
  Event classes 事gc?所有的事gc都定义在java.awt.event包中?

  Event sources 事g?产生事g的组件或对象UCؓ事g源?br />
  Exception 异常:异常是一U对象类?异常q指应用中发生的一U非标准程情况Q即异常状?br />
  Extensibility扩展?扩展性指的是面向对象E序中,不需要重写代码和重新设计Q能Ҏ?br />             增强源设计的功能?

  Finalizer 收尾:每个c都有一个特D的ҎfinalizerQ它不能被直接调用,而被JVM在适当?br />           时候调用,通常用来处理一些清理资源的工作Q因此称为收机制?

  Garbage collection 垃圾回收机制:当需要分配的内存I间不再使用的时候,JVM调用垃?br />           回收机制来回收内存空间?

  Guarded region 监控区域:一D는来监控错误生的代码?

  Heap?Java中管理内存的l构UC堆?

  Identifiers 标识W?x定类、方法、变量的名字。注意Java是大写敏感的语a?

  Import statement 引入语法:引入语法允许你可以不使用某个cȝ全名可以参考这个类?

  Inheritance l承:l承是面向对象程序设计的重要特点Q它是一U处理方法,通过q一ҎQ?br />             一个对象可以获得另一个对象的特征?

  Inner classes 内部c?内部cM一般的cȝ|只是它被声明在类的内部,或者甚x?br />             cL法体中?

  Instance 实例:cd例化以后成ؓ一个对象?

  Instance variable 实例变量

  Interface 接口:接口定义的是一l方法或者一个公共接口,它必通过cL实现?

  Java source file Java源文?Java源程序包含的是JavaE序语言计算机指令?

  Java Virtual Machine (JVM) Java虚拟?解释和执行Java字节码的E序Q其中Java字节?br />             由Java~译器生成?

  javac Java~译?Javac是Java~译E序的名U?

  JVM Java虚拟?见Java虚拟?

  Keywords 关键?即Java中的保留字,不能用作其他的标识符?

  Layout managers 布局理?布局理器是一些用来负责处理容器中的组件布局排列的类?

  Local inner classes 局部内部类:在方法体中,或者甚x的语句块中定义的内部类?

  Local variable 局部变?在方法体中声明的变量

  Member inner classes 成员内部c?定义在封装类中的没有指定static修饰W的内部cR?

  Members 成员:cM的元素,包括Ҏ和变量?

  Method Ҏ:完成特定功能的一D|代码Q可以传递参数和q回l果Q定义在cM?

  Method local variables Ҏ局部变?见自动变量Automatic variables

  Modifier 修饰W?用来修饰cR方法或者变量行为的关键字?

  Native methods 本地Ҏ:本地Ҏ是指使用依赖q_的语a~写的方法,它用来完成Java
                 无法处理的某些依赖于q_的功能?

  Object 对象:一旦类实例化之后就成ؓ对象?

  Overloaded methods 名称重蝲Ҏ:Ҏ的名U重载是指同一个类中具有多个方法,使用相同
                    的名U而只是其参数列表不同?

  Overridden methods 覆盖重蝲Ҏ:Ҏ的覆盖重载是指父cd子类使用的方法采用同L
                    名称、参数列表和q回cd?

  Package ?包即是将一些类聚集在一L一个实体?

  Parent class 父类:被其他类l承的类。也见基cR?

  Private members U有成员:U有成员只能在当前类被访问,其他Mc都不可以访问之?

  Public members 公共成员:公共成员可以被Q何类讉KQ而不该cd于那个包?

  Runtime exceptions q行旉异常:q行旉异常是一U不能被你自qE序处理的异常?br />                   通常用来指示E序BUG?

  Source file 源文?源文件是包含你的Java代码的一个纯文本文g?

  Stack trace 堆栈轨迹:如果你需要打印出某个旉的调用堆栈状态,你将产生一个堆栈轨qV?

  Static inner classes 静态内部类:静态内部类是内部类最单的形式Q它于一般的cd怼Q?br />                   除了被定义在了某个类的内部?

  Static methods 静态方?静态方法声明一个方法属于整个类Q即它可以不需要实例化一个类
                可以通过cȝ接访问之?

  Static variable 静态变?也可以称作类变量。它cM于静态方法,也是可以不需要实例化c?br />               可以通过cȝ接访问?

  Superclass 类:被一个或多个cȝ承的cR?

  Synchronized methods 同步Ҏ:同步Ҏ是指明某个方法在某个时刻只能׃个线E访问?

  Thread U程:U程是一个程序内部的序控制?

  Time-slicing 旉?调度安排U程执行的一U方案?

  Variable access 变量讉K控制:变量讉K控制是指某个c读或者改变一个其他类中的变量的能力?

  Visibility 可见? 可见性体CҎ和实例变量对其他cd包的讉K控制?


J2EE相关名词解释:

  容器Q充当中间g的角?

  WEB容器Q给处于其中的应用程序组ӞJSPQSERVLETQ提供一个环境,使JSP,SERVLET直接更容器中的环境变量接口交互,不必x其它pȝ问题。主要有WEB服务器来实现。例如:TOMCAT,WEBLOGIC,WEBSPHERE{。该容器提供的接口严格遵守J2EE规范中的WEB APPLICATION 标准。我们把遵守以上标准的WEB服务器就叫做J2EE中的WEB容器?

  EJB容器QEnterprise java bean 容器。更h行业领域特色。他提供l运行在其中的组件EJB各种理功能。只要满J2EE规范的EJB攑օ该容器,马上׃被容器进行高效率的管理。ƈ且可以通过现成的接口来获得pȝU别的服务。例如邮件服务、事务管理?

  WEB容器和EJB容器在原理上是大体相同的Q更多的区别是被隔离的外界环境。WEB容器更多的是跟基于HTTP的请求打交道。而EJB容器不是。它是更多的跟数据库、其它服务打交道。但他们都是把与外界的交互实C而减d用程序的负担。例如SERVLET不用兛_HTTP的细节,直接引用环境变量session,request,responsep、EJB不用兛_数据库连接速度、各U事务控Ӟ直接由容器来完成?

  RMI/IIOP:q程Ҏ调用/internet对象h中介协议Q他们主要用于通过q程调用服务。例如,q程有一台计机上运行一个程序,它提供股分析服务,我们可以在本地计机上实现对其直接调用。当然这是要通过一定的规范才能在异构的pȝ之间q行通信。RMI是JAVAҎ的?

  JNDI:JAVA命名目录服务。主要提供的功能是:提供一个目录系l,让其它各地的应用E序在其上面留下自己的烦引,从而满_速查扑֒定位分布式应用程序的功能?

  JMS:JAVA消息服务。主要实现各个应用程序之间的通讯。包括点对点和广播?

  JAVAMAIL:JAVA邮g服务。提供邮件的存储、传输功能。他是JAVA~程中实现邮件功能的核心。相当MS中的EXCHANGE开发包?

  JTAQJAVA事务服务。提供各U分布式事务服务。应用程序只需调用其提供的接口卛_?br />  
  JAF:JAVA安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部v和自定义实现自己的个性安全控制策略?

  EAI:企业应用集成。是一U概念,从而牵涉到好多技术。J2EE技术是一U很好的集成实现?br />


阿成 2006-09-05 10:11 发表评论
]]>
用过的类?/title><link>http://www.tkk7.com/ltc603/archive/2006/08/25/65799.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Fri, 25 Aug 2006 06:41:00 GMT</pubDate><guid>http://www.tkk7.com/ltc603/archive/2006/08/25/65799.html</guid><wfw:comment>http://www.tkk7.com/ltc603/comments/65799.html</wfw:comment><comments>http://www.tkk7.com/ltc603/archive/2006/08/25/65799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/ltc603/comments/commentRss/65799.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/ltc603/services/trackbacks/65799.html</trackback:ping><description><![CDATA[JDK<br />java.lang.*; <br />java.io.*; <br />java.util.*; <br />java.sql.*; <br /><img src ="http://www.tkk7.com/ltc603/aggbug/65799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/ltc603/" target="_blank">阿成</a> 2006-08-25 14:41 <a href="http://www.tkk7.com/ltc603/archive/2006/08/25/65799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式不断积累中http://www.tkk7.com/ltc603/archive/2006/08/21/64722.html阿成阿成Mon, 21 Aug 2006 02:02:00 GMThttp://www.tkk7.com/ltc603/archive/2006/08/21/64722.htmlhttp://www.tkk7.com/ltc603/comments/64722.htmlhttp://www.tkk7.com/ltc603/archive/2006/08/21/64722.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/64722.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/64722.html.
regex.test转换成com/regex/test
用replaceAll转换
replaceAll中的W一个参数是一个正则表辄Q不是普通的字符串组?br />
replaceAll(".", "/") <===>Pattern.compile(".").matcher(str).replaceAll("/")

"."需加{义符Q要写成"\\.",如replaceAll("\\.", "/") 卛_?br />

阿成 2006-08-21 10:02 发表评论
]]>javaIO学习W记http://www.tkk7.com/ltc603/archive/2006/08/16/63944.html阿成阿成Wed, 16 Aug 2006 08:59:00 GMThttp://www.tkk7.com/ltc603/archive/2006/08/16/63944.htmlhttp://www.tkk7.com/ltc603/comments/63944.htmlhttp://www.tkk7.com/ltc603/archive/2006/08/16/63944.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/63944.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/63944.htmlW一?a >http://www.blueidea.com/bbs/newsdetail.asp?id=996916Q里面有很多例子Q?br />
W二、彻底明白Java的IOpȝ(文摘Q?--JAVA之精髓IO?br />一Q?Input和Output
1. stream代表的是M有能力出数据的数据源,或是M有能力接收数据的接收源。在Java的IO中,所有的streamQ包括Input和Out streamQ都包括两种cdQ?br />1.1 以字节ؓ导向的stream
以字节ؓ导向的streamQ表CZ字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种cdQ?br />1) input streamQ?br />1) ByteArrayInputStreamQ把内存中的一个缓冲区作ؓInputStream使用
2) StringBufferInputStreamQ把一个String对象作ؓInputStream
3) FileInputStreamQ把一个文件作为InputStreamQ实现对文g的读取操?br />4) PipedInputStreamQ实Cpipe的概念,主要在线E中使用
5) SequenceInputStreamQ把多个InputStream合ƈZ个InputStream
2) Out stream
1) ByteArrayOutputStreamQ把信息存入内存中的一个缓冲区?br />2) FileOutputStreamQ把信息存入文g?br />3) PipedOutputStreamQ实Cpipe的概念,主要在线E中使用
4) SequenceOutputStreamQ把多个OutStream合ƈZ个OutStream
1.2 以Unicode字符为导向的stream
以Unicode字符为导向的streamQ表CZUnicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种cdQ?br />1) Input Stream
1) CharArrayReaderQ与ByteArrayInputStream对应
2) StringReaderQ与StringBufferInputStream对应
3) FileReaderQ与FileInputStream对应
4) PipedReaderQ与PipedInputStream对应
2) Out Stream
1) CharArrayWriteQ与ByteArrayOutputStream对应
2) StringWriteQ无与之对应的以字节为导向的stream
3) FileWriteQ与FileOutputStream对应
4) PipedWriteQ与PipedOutputStream对应
? 字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,字是在操作时的导向不同。如 CharArrayReaderQ和ByteArrayInputStream的作用都是把内存中的一个缓冲区作ؓInputStream使用Q所不同? 是前者每ơ从内存中读取一个字节的信息Q而后者每ơ从内存中读取一个字W?br />1.3 两种不现导向的stream之间的{?br />InputStreamReader和OutputStreamReaderQ把一个以字节为导向的stream转换成一个以字符为导向的stream?br />2. streamd属?br />2.1 “ؓstreamd属性”的作用
q用上面介绍的Java中操作IO的APIQ我们就可完成我们想完成的Q何操作了。但通过FilterInputStream和FilterOutStream的子c,我们可以为streamd属性。下面以一个例子来说明q种功能的作用?br />如果我们要往一个文件中写入数据Q我们可以这h作:
FileOutStream fs = new FileOutStream(“test.txt?;
? 后就可以通过产生的fs对象调用write()函数来往test.txt文g中写入数据了。但是,如果我们惛_现“先把要写入文g的数据先~存到内存中Q? 再把~存中的数据写入文g中”的功能Ӟ上面的API没有一个能满我们的需求了。但是通过FilterInputStream? FilterOutStream的子c,为FileOutStreamd我们所需要的功能?br />2.2 FilterInputStream的各U类?br />2.2.1 用于装以字节ؓ导向的InputStream
1) DataInputStreamQ从stream中读取基本类型(int、char{)数据?br />2) BufferedInputStreamQ用缓冲区
3) LineNumberInputStreamQ会记录input stream内的行数Q然后可以调用getLineNumber()和setLineNumber(int)
4) PushbackInputStreamQ很用刎ͼ一般用于编译器开?br />2.2.2 用于装以字Wؓ导向的InputStream
1) 没有与DataInputStream对应的类。除非在要用readLine()时改用BufferedReaderQ否则用DataInputStream
2) BufferedReaderQ与BufferedInputStream对应
3) LineNumberReaderQ与LineNumberInputStream对应
4) PushBackReaderQ与PushbackInputStream对应
2.3 FilterOutStream的各U类?br />2.2.3 用于装以字节ؓ导向的OutputStream
1) DataIOutStreamQ往stream中输出基本类型(int、char{)数据?br />2) BufferedOutStreamQ用缓冲区
3) PrintStreamQ生格式化输出
2.2.4 用于装以字Wؓ导向的OutputStream
1) BufferedWriteQ与对应
2) PrintWriteQ与对应
3. RandomAccessFile
1) 可通过RandomAccessFile对象完成Ҏ件的d操作
2) 在生一个对象时Q可指明要打开的文件的性质QrQ只读;wQ只写;rw可读?br />3) 可以直接跛_文g中指定的位置
4. I/O应用的一个例?br />import java.io.*;
public class TestIO{
public static void main(String[] args)
throws IOException{
//1.以行为单位从一个文件读取数?br />BufferedReader in =
new BufferedReader(
new FileReader("F:\\nepalon\\TestIO.java"));
String s, s2 = new String();
while((s = in.readLine()) != null)
s2 += s + "\n";
in.close();

//1b. 接收键盘的输?br />BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter a line:");
System.out.println(stdin.readLine());

//2. 从一个String对象中读取数?br />StringReader in2 = new StringReader(s2);
int c;
while((c = in2.read()) != -1)
System.out.println((char)c);
in2.close();

//3. 从内存取出格式化输入
try{
DataInputStream in3 =
new DataInputStream(
new ByteArrayInputStream(s2.getBytes()));
while(true)
System.out.println((char)in3.readByte());
}
catch(EOFException e){
System.out.println("End of stream");
}

//4. 输出到文?br />try{
BufferedReader in4 =
new BufferedReader(
new StringReader(s2));
PrintWriter out1 =
new PrintWriter(
new BufferedWriter(
new FileWriter("F:\\nepalon\\ TestIO.out")));
int lineCount = 1;
while((s = in4.readLine()) != null)
out1.println(lineCount++ + "Q? + s);
out1.close();
in4.close();
}
catch(EOFException ex){
System.out.println("End of stream");
}

//5. 数据的存储和恢复
try{
DataOutputStream out2 =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("F:\\nepalon\\ Data.txt")));
out2.writeDouble(3.1415926);
out2.writeChars("\nThas was pi:writeChars\n");
out2.writeBytes("Thas was pi:writeByte\n");
out2.close();
DataInputStream in5 =
new DataInputStream(
new BufferedInputStream(
new FileInputStream("F:\\nepalon\\ Data.txt")));
BufferedReader in5br =
new BufferedReader(
new InputStreamReader(in5));
System.out.println(in5.readDouble());
System.out.println(in5br.readLine());
System.out.println(in5br.readLine());
}
catch(EOFException e){
System.out.println("End of stream");
}

//6. 通过RandomAccessFile操作文g
RandomAccessFile rf =
new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
for(int i=0; i<10; i++)
rf.writeDouble(i*1.414);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + "Q? + rf.readDouble());
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + "Q? + rf.readDouble());
rf.close();
}
}
关于代码的解释(以区为单位)Q?br />1ZQ当d文gӞ先把文g内容d~存中,当调用in.readLine()Ӟ再从~存中以字符的方式读取数据(以下U“缓存字节读取方式”)?br />1bZQ由于想以缓存字节读取方式从标准IOQ键盘)中读取数据,所以要先把标准IOQSystem.inQ{换成字符导向的streamQ再q行BufferedReader装?br />2ZQ要以字W的形式从一个String对象中读取数据,所以要产生一个StringReadercd的stream?br />4ZQ对String对象s2d数据Ӟ先把对象中的数据存入~存中,再从~冲中进行读取;对TestIO.out文gq行操作Ӟ先把格式化后的信息输出到~存中,再把~存中的信息输出到文件中?br />5 ZQ对Data.txt文gq行输出Ӟ是先把基本类型的数据输出屋缓存中Q再把缓存中的数据输出到文g中;Ҏ件进行读取操作时Q先把文件中的数据读 取到~存中,再从~存中以基本cd的Ş式进行读取。注意in5.readDouble()q一行。因为写入第一个writeDouble()Q所以ؓ了正 显C。也要以基本cd的Ş式进行读取?br />6区是通过RandomAccessFilecd文gq行操作?/p>

W三、花1K内存实现高效I/O的RandomAccessFilec(http://www-128.ibm.com/developerworks/cn/java/l-javaio/index.htmlQ,解决RandomAccessFilecL率低下的问题Q特别是?a name="5">与JDK1.4新类MappedByteBuffer+RandomAccessFile的对?/font>”部分讲了怎样用jdk自己的功能实现?/p>

阿成 2006-08-16 16:59 发表评论
]]>
查询字符串是否含有汉字(是否含有gb2312格式的字W)http://www.tkk7.com/ltc603/archive/2006/08/16/63935.html阿成阿成Wed, 16 Aug 2006 08:38:00 GMThttp://www.tkk7.com/ltc603/archive/2006/08/16/63935.htmlhttp://www.tkk7.com/ltc603/comments/63935.htmlhttp://www.tkk7.com/ltc603/archive/2006/08/16/63935.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/63935.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/63935.html//本例是验证此串是否含有gb2312格式的字W,x否含有汉?br />public class Test{
  public boolean isGB2312( String str )
  {
    char[] chars = str.toCharArray();
    boolean isGB2312 = false;
    for ( int i = 0; i < chars.length; i++ )
    {
      byte[] bytes = ( "" + chars[i] ).getBytes();
      if ( bytes.length == 2 )
      {
        int[] ints = new int[2];
        ints[0] = bytes[0] & 0xff;
        ints[1] = bytes[1] & 0xff;
        if ( ints[0] >= 0x81 && ints[0] <= 0xFE && ints[1] >= 0x40 && ints[1] <= 0xFE )
        {
          isGB2312 = true;
          break;
        }
      }
    }
    return isGB2312;
  }
 
  public static void main(String[] args)
  {
    String s = "ss您好ss";//l果为true
    String s = "ssssss";//l果为false
    Test test = new Test();
    System.out.println(test.isGB2312(s));
  }
}

阿成 2006-08-16 16:38 发表评论
]]>
JAVA&J2EE FAQhttp://www.tkk7.com/ltc603/archive/2006/08/16/63899.html阿成阿成Wed, 16 Aug 2006 06:43:00 GMThttp://www.tkk7.com/ltc603/archive/2006/08/16/63899.htmlhttp://www.tkk7.com/ltc603/comments/63899.htmlhttp://www.tkk7.com/ltc603/archive/2006/08/16/63899.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/63899.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/63899.htmlJava FAQ
 
目录Q?br />Q1.1 什么是Java、Java2、JDKQJDK后面?.3?.4版本号又是怎么回事Q?br />Q1.2 什么是JRE/J2REQ?br />Q1.3 学习Java用什么工h较好Q?br />Q1.4  学习Java有哪些好的参考书Q?br />Q1.5  Java和C++哪个更好Q?br />Q1.6  什么是J2SE/J2EE/J2MEQ?br />Q2.1  我写了第一个JavaE序Q应该如何编?q行Q?br />Q2.2  我照你说的做了,但是出现什么?javac' 不是内部或外部命令,也不是可q行?br />E序或批处理文g。”?br />Q2.3  环境变量怎么讄Q?br />Q2.4  我在javac xxx.java的时候显CZ么“unreported exception java.io.IOExcepti
on;”?br />Q2.5  javac xxx.java利通过了,但是java xxx的时候显CZ么“NoClassDefFoundErr
or”?br />Q2.6  我在java xxx的时候显C“Exception in thread "main" java.lang.NoSuchMetho
dError: main”?br />Q2.7  在java xxx的时候显C“Exception in thread "main" java.lang.NullPointerEx
ception”?br />Q2.8 package是什么意思?怎么用?
Q2.9 我没有声明Q何package会怎么P
Q2.10 在一个类中怎么使用其他c?
Q2.11 我用了package的时候显C?NoClassDefFoundError"Q但是我把所有packageL?br />时候能正常q行?br />Q2.12 我想把java~译成exe文gQ该怎么做?
Q2.13 我在~译的时候遇C?deprecated API"Q是什么意思?
Q3.1 我怎么ljavaE序加启动参敎ͼ像dir /p/w那样Q?br />Q3.2 我怎么从键盘输入一个int/double/字符Ԍ
Q3.3 我怎么输出一个int/double/字符Ԍ
Q3.4 我发现有些书上直接用System.in输入Q比你要单得多?br />Q3.5 我怎么从文件输入一个int/double/字符Ԍ
Q3.6 我想d文g的指定位|,该怎么办?
Q3.7 怎么判断要读的文件已l到了尽_
Q4.1  java里面怎么定义宏?
Q4.2  java里面没法用const?br />Q4.3  java里面也不能用goto?br />Q4.4  java里面能不能重载操作符Q?br />Q4.5  我new了一个对象,但是没法delete掉它?br />Q4.6  我想知道Z么mainҎ必须被声明ؓpublic staticQؓ什么在mainҎ中不能调
用非static成员Q?br />Q4.7  throw和throws有什么不同?
Q4.8  什么是异常Q?br />Q4.9  final和finally有什么不同?
Q5.1  extends和implements有什么不同?
Q5.2  java怎么实现多承?
Q5.3 abstract是什么?
Q5.4 public,protected,private有什么不同?
Q5.5 Override和Overload有什么不同?
Q5.6 我承了一个方法,但现在我惌用在父类中定义的Ҏ?br />Q5.7 我想在子cȝ构造方法中调用父类的构造方法,该怎么办?
Q5.8 我在同一个类中定义了好几个构造方法ƈ且想在一个构造方法中调用另一个?br />Q5.9 我没有定义构造方法会怎么P
Q5.10 我调用无参数的构造方法失败了?br />Q5.11 我该怎么定义cM于C++中的析构ҎQdestructorQ?
Q5.12 我想一个父cd象{换成一个子cd象该怎么做?
Q5.13 其实我不定a是不是B的实例,能不能分情况处理Q?br />Q5.14 我在Ҏ里修改了一个对象的|但是退出方法后我发现这个对象的值没变!
Q6.1 java能动态分配数l吗Q?br />Q6.2 我怎么知道数组的长度?
Q6.3 我还惌数组的长度能自动改变Q能够增?删除元素?br />Q     什么是链表Qؓ什么要有ArrayList和LinkedList两种ListQ?br />Q6.5 我想用队?栈?br />Q6.6 我希望不要有重复的元素?br />Q6.7 我想遍历集合/Map?br />Q6.8 我还要能够排序?br />Q6.9 但是我想l数l排序?br />Q6.10 我想按不同方式排序?br />Q6.11 Map有什么用Q?br />Q6.12 setҎ没问题,但是getҎq回的是Object?br />Q6.13 ArrayList和Vector有什么不同?HashMap和Hashtable有什么不同?
Q6.14 我要获得一个随机数?br />Q6.15 我比较两个StringLfalseQ但是它们明明都?abc" Q?br />Q6.16 我想修改一个String但是在StringcM没找到编辑方法?br />Q6.17 我想处理日期/旉?/p>

一、准备篇

Q1.1 什么是Java、Java2、JDKQJDK后面?.3?.4版本号又是怎么回事Q?br />{:Java是一U通用的,q发的,强类型的Q面向对象的~程语言Q摘自Java规范W二?br />Q?br />JDK是Sun公司分发的免费Java开发工具包Q正式名UCؓJ2SDK(Java2 Software Develop K
it)?br />包括基本的java工具包和标准cd?br />到目?2003q??为止QJava?个主要版本,?.0Q?.1Q?.0Q?br />JDK?.0Q?.1Q?.2Q?.3Q?.4五个版本?br />从JDK1.2PSun公司觉得Java改变_大而将java语言版本h升ؓ2.0?br />不同的JDK主要在于提供的类库不同。作为学习你可以下蝲最新的JDK1.4.2?br />真正开发时则应考虑向前兼容Q比?.3。下载请?a >http://java.sun.com?br />JDK1.5预计在2004q推出,届时其中包含若q崭新的Ҏ?/p>

Q1.2 什么是JRE/J2REQ?br />{:J2RE是Java2 Runtime EnvironmentQ即Javaq行环境Q有时简UJRE?br />如果你只需要运行JavaE序或AppletQ下载ƈ安装它即可?br />如果你要自行开发Java软gQ请下蝲JDK。在JDK中附带有JRE?br />注意׃Microsoft对Java的支持不完全Q请不要使用IE自带的虚拟机来运行AppletQ务?br />安装一个JRE或JDK?/p>

Q1.3 学习Java用什么工h较好Q?br />{:作者徏议首先用JDK+文本~辑器,q有助你理解下列几个基础概念QpathQclassp
athQpackage
q熟悉基本命令:javac和java。ƈ且下载和你的JDK版本一致的API帮助?br />如果你不定cL函数的用法,请先查阅API而不是发贴求助?br />当你熟悉Java之后Q你可以考虑开始用一个IDE?br />作者推荐eclipseQ下载网址http://www.eclipse.org。因为eclispe是免费的Q插件化?br />?br />eclispe的主要缺Ҏ~Z一个可视化的桌面程序开发工P
q运的是IBM?003q?1月已l将部分代码捐给eclipsel织Q可以预计这个缺点很快就?br />得到弥补?br />无论如何Q请不要使用Microsoft的VJ++Q众所周知Microsoft从来没有认真支持过Java
?br />最后但q最不重要,要有一本好的参考书Qƈ且英文要q关?/p>

Q1.4  学习Java有哪些好的参考书Q?br />{:作者首先推荐Thinking in JavaQ中文名《Java~程思想》,有中文版?br />目前的最新版本是W三版?br />?a >http://64.78.49.204可以免费下蝲英文版?br />该书W一章介l了很多面向对象的编E思想Q作为新手应当认真阅诅R?br />除此以外QO'relly出版C֒Wrox出版C书也不错。作者本Z喜欢大陆作者的书?br />也许你觉得英文太难,但是|上大多数资料都是英文的。另外,你需要经常查阅APIQ而那
也是英文的?/p>

Q1.5  Java和C++哪个更好Q?br />{:q个问题是一个很不恰当的问题。你应该问:Java和C++哪个更适用于我的项目?
Java的优点和~点一h显?br />跨^台是Java的主要优点,但代hq行速度的下降?br />VC和Windowsq_有良好的集成和够快的速度Q但是也只能局限在Windowsq_上?br />和C++相比QJava学v来更快,开发h员不会碰到很多容易出错的Ҏ?br />但是VBE序员甚臛_需要拼装模块就可以了?/p>

Q1.6  什么是J2SE/J2EE/J2MEQ?br />{:J2SE是一般的Java?br />J2ME是针对嵌入式讑֤的,比如支持Java的手机,它有自己的JRE和SDK?br />J2EE是一l用于企业E序开发的规范和类库,它用J2SE的JRE?/p>

二、命令篇

Q2.1  我写了第一个JavaE序Q应该如何编?q行Q?br />{:首先请将E序保存为xxx.java文gQ注意你可能需要修Ҏ件后~名?br />然后在dosH口下用javac xxx.java命oQ你会发现该目录下多了一个xxx.class文gQ?/p>

再用java xxx命oQ你的javaE序开始运行了?/p>

Q2.2  我照你说的做了,但是出现什么?javac' 不是内部或外部命令,也不是可q行?br />E序或批处理文g。”?br />{:你遇Cpath问题。操作系l在一定的范围(path)内搜索javac.exeQ但是没能找到?/p>

L辑你的操作系l环境变量,新增一个JAVA_HOME变量Q设ZJDK的安装目录,
再编辑Path变量Q加上一?%JAVA_HOME%\bin?br />然后保存q新开一个dosH口Q你可以用javac和java命o了?/p>

Q2.3  环境变量怎么讄Q?br />{:请向w边会设的h咨询?/p>

Q2.4  我在javac xxx.java的时候显CZ么“unreported exception java.io.IOExcepti
on;”?br />{:参见Q4.8以了解java中的异常机制?/p>

Q2.5  javac xxx.java利通过了,但是java xxx的时候显CZ么“NoClassDefFoundErr
or”?br />{:1. 你遇Cclasspath问题。java命o在一定的范围(classpath)内搜索你直接或间?br />使用的class文gQ但是未能找到?br />首先L认你没有错敲成java xxx.classQ?br />其次Q检查你的CLASSPATH环境变量Q其实你q不需要设|该变量Q?br />但如果你讄了该变量又没有包?Q代表当前目录)的项Q?br />你就会遇到这个问题。请在你的CLASSPATH环境变量中加入一? 或干脆删掉这个变量?/p>

2. 如果你用了qJDK自带的标准包Q比如javax.servlet.*包,也会遇到q个问题Q请
相应的jar文g加入classpath?br />3. 如果你在java源文件中定义了packageQ请参见Q2.11?/p>


Q2.6  我在java xxx的时候显C“Exception in thread "main" java.lang.NoSuchMetho
dError: main”?br />{:首先Q在你的E序中每个java文g有且只能有一个publicc,
q个cȝcd必须和文件名的大写完全一栗?br />其次Q在你要q行的类中有且只能有一个public static void main(String[] args)Ҏ
Q?br />q个Ҏ是你的ȝ序?/p>


Q2.7  在java xxx的时候显C“Exception in thread "main" java.lang.NullPointerEx
ception”?br />{:在程序中你试囑֜gؓnull的对象变量上调用ҎQ请查你的程序确保你的对象被恰当的初始化?br />参见Q4.8以了解java中的异常机制?/p>


Q2.8 package是什么意思?怎么用?
{:Z唯一标识每个cdƈ分组Qjava使用了package的概c?br />每个c都有一个全名,例如String的全名是java.lang.StringQ其中java.lang是包名,S
tring是短名。按照java命名惯例Q包名是全部写的,而类名的W一个字母是大写的?br />q样Q如果你自行定义了同样名字的cStringQ你可以把它攑֜mypackage中,
通过使用全名mypackage.String和java.lang.String来区分这两个cR?br />同时Q将逻辑上相关的cL在同一个包中,可以使程序结构更为清楚?br />Z定义包,你要做的是在java文g开头加一行“package mypackage;”?br />注意包没有嵌套或包含关系Qmypackage包和mypackage.mysubpackage包对JRE来说是ƈ列的两个包(虽然开发者可
能暗C包含关p)?/p>

Q2.9 我没有声明Q何package会怎么P
{:你的c被认ؓ攑֜默认包中。这时全名和短名是一致的?/p>

Q2.10 在一个类中怎么使用其他c?
{:如果你用java.lang包或者默认包中的c,不用做Q何事?br />如果你的cM于mypackage包中Qƈ且要调用同一包中的其他类Q也不用做Q何事?br />如果你用其他包中的c,在package声明之后Q类声明之前使用import otherpackage1.Class
1; ?import otherpackage2.*; 
q里.*表示引入q个包中的所有类。然后在E序中你可以使用其他cȝ短名?br />如果短名间有重名冲突Q必M用全名来区分?br />注意在用其他包中的cLQ你只能使用public的类和接口,参见Q5.4?/p>

Q2.11 我用了package的时候显C?NoClassDefFoundError"Q但是我把所有packageL?br />时候能正常q行?br />{:你的java文g按包名组l存放?br />比如你的工作目录?workQ你的类是package1.Class1Q那么将它存放ؓ/work/package1
/Class1.java?br />如果没有声明包,那么直接攑֜/work下?br />?work下执行javac package1/class1.javaQ再执行java package1.class1Q你会发C
切正常?br />另外Q如果你的类的个数已l多C你需要用包来组l的话,你可以考虑开始用IDE?/p>

Q2.12 我想把java~译成exe文gQ该怎么做?
{:JDK只能java源文件编译ؓclass文g?br />class文g是一U跨q_的字节码Q必M赖^台相关的JRE来运行。Java以此来实现跨q?br />台性?br />有些开发工具可以将java文g~译为exe文g。作者反对这U做法,因ؓq样取消了跨^
台性?br />如果你确信你的Y件只在Windowsq_上运行,你可以考虑使用C++/C#来编E?/p>

Q2.13 我在~译的时候遇C?deprecated API"Q是什么意思?
{:所谓deprecated是指已经q时Q但是ؓ了向前兼容v见仍然保留的Ҏ?br />q些Ҏ可能会在以后取消支持。你应当改用较新的方法?br />在API里面会说明你应当用什么方法来代替之?/p>

三、I/O?/p>

Q3.1 我怎么ljavaE序加启动参敎ͼ像dir /p/w那样Q?br />{:q记得public static void main(String[] args)吗?q里的args是你的启动参数
?br />在运行时你输入java package1.class1 arg1 arg2Qargs中就会有两个StringQ第一个是
arg1Q第二个是arg2?/p>

Q3.2 我怎么从键盘输入一个int/double/字符Ԍ
{:java的I/O操作比C++要复杂一炏V如果要从键盘输入,样例代码如下Q?br />BufferedReader cin = new BufferedReader( new InputStreamReader( System.in ) );

String s = cin.readLine();
q样你就获得了一个字W串Q如果你需要数字的话再使用Q?br />int n = Integer.parseInt( s ); 或?double d = Double.parseDouble( s );
来将字符?534"转换成int或double?/p>

Q3.3 我怎么输出一个int/double/字符Ԍ
{:使用System.out.println(n)或者System.out.println("Hello"){等?/p>

Q3.4 我发现有些书上直接用System.in输入Q比你要单得多?br />{:java使用unicodeQ是双字节。而System.in是单字节的stream?br />如果你要输入双字节文字比如中文,请用作者的做法?/p>

Q3.5 我怎么从文件输?输出一个int/double/字符Ԍ
{:cM于从键盘输入Q只不过换成
BufferedReader fin = new BufferedReader( new FileReader(" myFileName " ) );
PrintWriter fout = new PrintWriter( new FileWriter(" myFileName " ) );
另外如果你还没下载APIQ请开始下载ƈ阅读java.io包中的内宏V?/p>

Q3.6 我想d文g的指定位|,该怎么办?
{:java.io.RandomAccessFile可以满你的需要?/p>

Q3.7 怎么判断要读的文件已l到了尽_
{:在Reader的readҎ中明说明返?1表示的l尾?/p>

四?关键字篇

Q4.1  java里面怎么定义宏?
{:java不支持宏Q因为宏代换不能保证cd安全?br />如果你需要定义常量,可以它定义为某个类的static final成员。参见Q4.2和Q4.6?/p>


Q4.2  java里面没法用const?br />{:你可以用final关键字。例?final int m = 9。被声明为final的变量不能被再次?br />倹{唯一的例外是所谓blank finalQ如下例所C:
public class MyClass1 {
    private final int a = 3;
    private final int b; // blank final

    public MyClass1() {
        a = 5; // 不合法,final变量不能被再ơ赋倹{?br />        b = 4; // 合法Q这是bW一ơ被赋倹{?br />        b = 6; // 不合法,b不能被再ơ赋倹{?br />    }
}
final也可以用于声明方法或c,被声明ؓfinal的方法或cM能被l承?br />注意const是java的保留字以备扩充?/p>

Q4.3  java里面也不能用goto?br />{:甚至在面向过E的语言中你也可以完全不用goto。请查你的程序流E是否合理?/p>

如果你需要从多层循环中迅速蟩出,java增强了(和C++相比Qbreak和continue的功能,
支持label?br />例如Q?br />outer :
while( ... )
{
inner :
for( ... )
{
           ...   break inner; ...
           ... continue outer; ...
}
}
和const一Pgoto也是java的保留字以备扩充?/p>

Q4.4  java里面能不能重载操作符Q?br />{:不能。String?h唯一一个内|的重蝲操作W。你可以通过定义接口和方法来实现
cM功能?/p>

Q4.5  我new了一个对象,但是没法delete掉它?br />{:java有自动内存回收机Ӟx谓Garbarge Collection。你不需要删除对象。你再也
不用担心指针错误Q内存溢Z?/p>

Q4.6  我想知道Z么mainҎ必须被声明ؓpublic staticQؓ什么在mainҎ中不能调
用非static成员Q?br />{:声明为public是ؓ了这个方法可以被外部调用Q详情见Q5.4?br />static是ؓ了将某个成员变量/Ҏ兌到类QclassQ而非实例QinstanceQ?br />你不需要创Z个对象就可以直接使用q个cȝstatic成员Q因而在static成员中不能调
用非static成员Q因为后者是兌到对象实例(instanceQ的?br />在AcM调用Bcȝstatic成员可以使用B.staticMember的写法?br />注意一个类的static成员变量是唯一的,被所有该cd象所׃n的,在多U程E序设计中尤其要谨慎心?br />cȝstatic成员是在cȝ一ơ被JRE装蝲的时候初始化的?br />你可以用如下方法来使用非static成员Q?br />public class A
{
    private void someMethod() //非static成员
    {}
    public static void main(String args)
    {
         A a = new A();  //创徏一个对象实?br />         a.someMethod();  //现在你可以用非staticҎ?br />    }
}


Q4.7  throw和throws有什么不同?
{:throws用于Ҏ声明中,声明一个方法会抛出哪些异常。而throw是在Ҏ体中实际执行抛出异常?br />动作?br />如果你在Ҏ中throw一个异常,却没有在Ҏ声明中声明之Q编译器会报错?br />注意Error和RuntimeException的子cL例外Q无需特别声明?/p>

Q4.8  什么是异常Q?br />{:异常最早在Ada语言中引入,用于在程序中动态处理错误ƈ恢复?br />你可以在Ҏ中拦截底层异常ƈ处理之,也可以抛l更高层的模块去处理?br />你也可以抛出自己的异常指C发生了某些不正常情c常见的拦截处理代码如下Q?br />try
{
......//以下是可能发生异常的代码
        ...... //异常被你或低层API抛出Q执行流E中断ƈ转向拦截代码?br />        ......
}
catch(Exception1 e) //如果Exception1是Exception2的子cdƈ要做特别处理Q应排在?br />?br />{
  //发生Exception1时被该段拦截
}
catch(Exception2 e)
{
  //发生Exception2时被该段拦截
}
finally //q是可选的
{
   //无论异常是否发生Q均执行此段代码
   //即在catchD中又向外抛Z新的exceptionQfinallyD也会得到执行?br />}

Q4.9  final和finally有什么不同?
{:final误Q4.2。finally用于异常机制Q参见Q4.8?/p>

五?面向对象?/p>

Q5.1  extends和implements有什么不同?
{:对于class而言Qextends用于Q单Q承一个类QclassQ,而implements用于实现一个接口(interf
aceQ?br />interface的引入是Z部分地提供多l承的功能?br />在interface中只需声明Ҏ_而将Ҏ体留l实现的class来做?br />q些实现的class的实例完全可以当作interface的实例来对待?br />在interface之间也可以声明ؓextendsQ多l承Q的关系?br />注意一个interface可以extends多个其他interface?/p>

Q5.2  java怎么实现多承?
{:java不支持显式的多ѝ?br />因ؓ在显式多l承的语a例如c++中,会出现子c被q声明祖先虚基类构造函数的问题Q?/p>

而这是违反面向对象的装性原则的?br />java提供了interface和implements关键字来部分地实现多l承。参见Q5.1?/p>

Q5.3 abstract是什么?
{:被声明ؓabstract的方法无需l出Ҏ体,留给子类来实现?br />而如果一个类中有abstractҎQ那么这个类也必d明ؓabstract?br />被声明ؓabstract的类无法实例化,管它可以定义构造方法供子类使用?/p>

Q5.4 public,protected,private有什么不同?
{:q些关键字用于声明类和成员的可见性?br />public成员可以被Q何类讉KQ?br />protected成员限于自己和子c访问,
private成员限于自己讉K?br />Javaq提供了W四U的默认可见性,一般称为package privateQ当没有Mpublic,protected,private修饰W时Q成?br />是同一包内可见?br />cd以用public或默认来修饰?br />

Q5.5 Override和Overload有什么不同?
{:Override是指父类和子cM间方法的l承关系Q这些方法有着相同的名U和参数cd
?br />Overload是指同一个类中不同方法(可以在子cM可以在父cM定义Q间的关p,
q些Ҏ有着相同的名U和不同的参数类型?/p>


Q5.6 我承了一个方法,但现在我惌用在父类中定义的Ҏ?br />{:用super.xxx()可以在子cM调用父类Ҏ?/p>

Q5.7 我想在子cȝ构造方法中调用父类的构造方法,该怎么办?
{:在子cL造方法的W一行调用super(...)卛_?/p>

Q5.8 我在同一个类中定义了好几个构造方法ƈ且想在一个构造方法中调用另一个?br />{:在构造方法第一行调用this(...)?/p>

Q5.9 我没有定义构造方法会怎么P
{:自动获得一个无参数的构造方法?/p>

Q5.10 我调用无参数的构造方法失败了?br />{:如果你至定义了一个构造方法,׃再有自动提供的无参数的构造方法了?br />你需要另外显式定义一个无参数的构造方法?br />另外一U可能是你的构造方法或者类不是public的,参见Q5.4了解java中的可见性?/p>

Q5.11 我该怎么定义cM于C++中的析构ҎQdestructorQ?
{:提供一个void finalize()Ҏ。在Garbarge Collector回收该对象时会调用该Ҏ?/p>

注意实际上你很难判断一个对象会在什么时候被回收。作者从未感到需要用到该Ҏ?/p>


Q5.12 我想一个父cd象{换成一个子cd象该怎么做?
{:强制cd转换。如
public void meth(A a)
{
B b = (B)a;
}
如果a实际上ƈ不是B的实例,会抛出ClassCastException。所以请保a实是B的实例?/p>


Q5.13 其实我不定a是不是B的实例,能不能分情况处理Q?br />{:可以使用instanceof操作W。例?br />if( a instanceof B )
{
B b = (B)a;
}
else
{
...
}

Q5.14 我在Ҏ里修改了一个对象的|但是退出方法后我发现这个对象的值没变!
{:很可能你把传入参数重赋了一个新对象Q例如下列代码就会造成q种错误Q?br />public void fun1(A a) //a是局部参敎ͼ指向了一个外在对象?br />{
a = new A(); //a指向了一个新对象Q和外在对象脱钩了。如果你要让a作ؓ传出变量Q?br />不要写这一句?br />        a.setAttr(attr);//修改了新对象的|外在对象没有被修攏V?br />}
基本cd也会出现q种情况。例如:
public void fun2(int a)
{
a = 10;//只作用于本方法,外面的变量不会变化?br />}

六、java.util?/p>

Q6.1 java能动态分配数l吗Q?br />{:可以。例如int n = 3; Language[] myLanguages = new Language[n];

Q6.2 我怎么知道数组的长度?
{:用length属性。如上例中的  myLanguages.length ׃ؓ 3?/p>

Q6.3 我还惌数组的长度能自动改变Q能够增?删除元素?br />{:用顺序表--java.util.List接口?br />你可以选择用ArrayList或是LinkedListQ前者是数组实现Q后者是链表实现?br />例如Q?List list = new ArrayList(); 或是 List list = new LinkedList();  ?/p>

Q    什么是链表Qؓ什么要有ArrayList和LinkedList两种ListQ?br />{:误习数据结构?/p>

Q6.5 我想用队?栈?br />{:用java.util.LinkedList?/p>

Q6.6 我希望不要有重复的元素?br />{:用集?-java.util.Set接口。例如:Set set = new HashSet()?/p>

Q6.7 我想遍历集合/Map?br />{:用java.util.Iterator。参见API?/p>

Q6.8 我还要能够排序?br />{:用java.util.TreeSet。例如:Set set = new TreeSet()。放q去的元素会自动排序
?br />你需要ؓ元素实现Comparable接口Q还可能需要提供equals()ҎQcompareTo()ҎQh
ashCode()Ҏ?/p>

Q6.9 但是我想l数l排序?br />{:java.util.Arrayscd含了sort{实用方法?/p>

Q6.10 我想按不同方式排序?br />{:为每U方式定义一个实C接口Comparator的排序类q和Arrays或TreeSetl合q用?/p>


Q6.11 Map有什么用Q?br />{:存储key-value的关键字-值对Q你可以通过关键字来快速存取相应的倹{?/p>

Q6.12 setҎ没问题,但是getҎq回的是Object?br />{:强制cd转换成你需要的cd。参见Q5.12?/p>

Q6.13 ArrayList和Vector有什么不同?HashMap和Hashtable有什么不同?
{:ArrayList和HashMap是多U程不安全的Q在多个U程中访问同一个ArrayList对象可能
会引起冲HƈD错误?br />而Vector和Hashtable是多U程安全的,即在多个线E中同时讉K同一个Vector对象也不
会引起差错?br />看v来我们更应该使用Vector和HashtableQ但是实际上Vector和Hashtable的性能太差Q?br />所以如果你不在多线E中使用的话Q还是应该用ArrayList和HashMap?/p>

Q6.14 我要获得一个随机数?br />{:使用java.util.RandomcR?/p>

Q6.15 我比较两个StringLfalseQ但是它们明明都?abc" Q?br />{:比较String一定要使用equals或equalsIgnoreCaseҎQ不要?== Q?br />==比较的是两个引用Q变量)是否指向了同一个对象,而不是比较其内容?/p>

Q6.16 我想修改一个String但是在StringcM没找到编辑方法?br />{:使用StringBuffercR?br />String str = "......."; //待处理的字符?br />StringBuffer buffer = new StringBuffer(str); //使用该字W串初始化一个StringBuf
fer
buffer.append("..."); //调用StringBuffer的相关API来编辑字W串
String str2 = buffer.toString(); //获得~辑后的字符丌Ӏ?br />另外Q如果你需要将多个字符串连接v来,请尽量避免?L接连接,而是使用Strin
gBuffer.append()Ҏ?/p>

Q6.17 我想处理日期/旉?br />{:使用java.util.DatecR你可以使用java.text.SimpleDateFormatcL在String和Da
te间互相{换?br />SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //?br />定日期格?br />Date date = formatter.parse("2003-07-26 18:30:35"); //符合格式的String转换?br />Date
String s = formatter.format(date); //Date转换为符合格式的String
关于定义日期格式的详l信息请参见API?br /> 

J2EE FAQ
 
目录Q?/p>

一、准备篇
Q1.1   什么是J2EEQ它和普通的Java有什么不同?
Q1.2   J2EE好学吗?
Q1.3   J2EE有什么用Q?br />Q1.4   学J2EE有前途吗Q?br />Q1.5   据说J2EE的性能不如.NET好,是真的吗Q?br />Q1.6   听你说了q么多,我想学着玩玩?br />Q1.7   学习J2EE该怎么开始?
Q1.8   我下了一个J2EE服务器但是不会配|?br />Q1.9   我发C没有提到Tomcat?/p>

二?Servlet/JSP?br />Q2.1   什么是ServletQ?br />Q2.2   我怎么获得Httph里的参数Q?br />Q2.3   我怎么q回l果Q?br />Q2.4   sendRedirect()和forward()有什么不同?
Q2.5   我写了一个ServletE序Q怎么q行它?
Q2.6   EAR和WAR有什么不同?
Q2.7   EAR格式是怎样的?
Q2.8   WAR格式是怎样的?
Q2.9   我的普通HTML文g/JSP文g应当攑֜哪里Q?br />Q2.10  我访问不到servletQ甚臌HTML文g都访问不刎ͼ
Q2.11  我能讉KHTML但是讉K不到servlet?br />Q2.12  什么是JSPQ它和Servlet有什么区别?
Q2.13  我的JSP昄的汉字是q?br />Q2.14  Z么用gb18030而不是gb2312Q?br />Q2.15  在JSP里面怎么引用Java Bean?br />Q2.16  我想在servlet间传递数据?br />Q2.17  怎么调用cookieQ?br />Q2.18  怎么在JSP里面实现文g下蝲Q?br />Q2.19  怎么实现文g上传Q?br />Q2.20  我想让页面自动刷斎ͼ比如聊天室?br />Q2.21  我想让用L录以后才能访问页面?br />Q2.22  我想要能注册用户?br />Q2.23  怎么在JSP中访问数据库Q?br />Q2.24  什么是JSTLQ?/p>

一、准备篇

Q1.1  什么是J2EEQ它和普通的Java有什么不同?
{:J2EE全称为Java2 Platform, Enterprise Edition?br />“J2EEq_本质上是一个分布式的服务器应用E序设计环境——一个Java环境Q它提供?br />Q?br />·宿主应用的一个运行基框架环境?br />·一套用来创建应用的Java扩展API。?/p>

Q1.2  J2EE好学吗?
{:J2EE是很多技术的集合体,q且q在成长中?br />你会遇到很多专有名词Q比?X)HTMLQServlet/JSPQJDBCQJMSQJNDIQEJBQXMLQWeb
Service……?br />其是XML和Web Service正在快速成ѝ幸q的是,你不需要等到学会所有技术后再开?br />~程?br />大体上J2EE可以分成3个主要应用方式:Servlet/JSPQEJBQWeb Service 和一些支撑技?br />例如JDBC和JNDI?br />你可以一个一个的学?/p>

Q1.3 J2EE有什么用Q?br />{:用来大型的分布式企业U应用程序。或者用更时髦的名词说就是“电子商务”应
用程序?br />q些企业可能大到拥有中心数据库服务器QWeb服务器集和遍布全国的办公终端,也可?br />到只不q想做一个网站。但是你肯定听过“杀鸡焉用牛刀”的古训?/p>

Q1.4 学J2EE有前途吗Q?br />{:在这一市场目前只有一U技术可以和J2EE竞争Q那是Microsoft?NET?br />相对来说.NET要“新”一些而J2EE要“老”一些。这也意味着.NET更易用一点而J2EE更成
熟一炏V?br />但是.NET只能用于Windowsq_QMicrosoft声称要开发C#在Linux上的虚拟Z是尚未兑?br />该诺aQ?br />在过dq_.NET的市Z额ƈ不理惟뀂不qMicrosoftq有Longhornq一杀手锏Q鹿死谁
手还很难说?/p>

Q1.5 据说J2EE的性能不如.NET好,是真的吗Q?br />{:在Sun公司提供的样例程序Pet Store上,Microsoft声称不如相同?NETE序好?br />而Sun公司反驳说这一E序不能真正体现J2EE的性能Qƈ且指责Microsoft在数据库上做?br />优化?br />作者没有学习过.NET因而不能妄下断a?br />无论如何Q大型分布式E序中的性能瓉通常首先来自于错误的设计?/p>

Q1.6 听你说了q么多,我想学着玩玩?br />{:除非你想靠它当饭吃或者作为技术储备,否则请不要浪费你的时间?br />Flash要好玩得多。计机游戏更加好玩了?/p>

Q1.7 学习J2EE该怎么开始?
{:首先Q下载一个免费的J2EE服务器。其ơ,去java.sun.com下蝲J2EE的API。第三,?br />一本好的参考书。最后,找一个顺手的IDE?br />J2EE服务器。你可以用Sun的J2EE SDKQ免费)Q或者WeblogicQ性能最好,但是太大Q?br />且作者不推荐盗版行ؓQ,
或者JBossQ免费,是文档太少Q,或者JRunQ开发版免费Q作者用q个Q?br />参考书作者感觉Wrox的《J2EE服务器端高~程》不错,但是太老(作者手头的?001q?br />中文版)?br />Q似乎很多h不喜Ƣ这本书......所以你得自己判断它是否适合你。)
你还需要去下蝲一些最新的技术资料(当然肯定是英文的Q?br />IDE如果你的机器配置够好Q内存至?12M以上Q?56M或以下请勿考虑Q,可以用IBM的WS
ADQ不然就l箋用Eclipse或者其他?br />你也可以l常L木清华的Java版逛逛,但是在发贴前先看看精华区里有没有你要的答?br />?/p>

Q1.8 我下了一个J2EE服务器但是不会配|?br />{:误真阅读随机指导文,不同的服务器的配|都不一P作者爱莫能助?/p>

Q1.9 我发C没有提到Tomcat?br />{:Tomcat只是一个Web服务器,更准地说主要只是一个Web Container?br />如果你想要学习EJB的话QTomcat无法满你的需要?/p>

二?Servlet/JSP?/p>

Q2.1 什么是ServletQ?br />{:一个Servlet是一个JavacR它处理Http(s)hq作出响应,包括q回一个HTML面
或{交给其他URL处理?br />Servlet必须q行在一个Web Container例如Tomcat中?br />Servlet必须是javax.servlet.http.HttpServlet的子c,
你可以承doGet()或者doPost()ҎQ两者分别对应于Http(s)中的Geth和Posth?/p>


Q2.2 我怎么获得Httph里的参数Q?br />{:HttpRequest的getParameter()Ҏ。例如:String paramValue = request.getPara
meter("paramName");

Q2.3 我怎么q回l果Q?br />{:你可以利用相关API打开一个输出流Qƈ向流中直接写入一个HTML面?br />但是作者完全不赞成q样做。一斚wq样做会很罗嗦?br />另一斚w从Model-View-Controller模式Q在《J2EE核心模式》中被归为Front Controlle
r模式Q的观点来看Q?br />你应当提供一些HTML或者JSP作ؓ视图QviewQ,而Servlet则根据请求参数决定{到哪一
个视图?br />你可以利用response.sendRedirect(...)Ҏ或request.getDispatcher(...).forward()
Ҏ来实现?/p>

Q2.4 sendRedirect()和forward()有什么不同?
{:sendRedirect()是向览器发送一个redirect通知Q浏览器向新的URL发送一个新的请
求?br />而forward是在服务器端直接请求{到新的URLQ对于浏览器是透明的?br />换而言之,sendRedirect()应当共享数据放在session中,forward应当共享数据放?br />request中(当然你也可以攑֜session中,但放在request中可以有效减session中的?br />据量Q从而改善性能Q?br />前者浏览器的地址栏显C的是新的URLQ后者浏览器的地址栏显C的是Servlet的URL?br />因而当h目标URLӞ两者会造成一些差别?/p>

Q2.5 我写了一个ServletE序Q怎么q行它?
{:开发J2EEE序有一个部|ԌdeployQ的概念Q实际上是开发——部|y—运行的三部
曌Ӏ?br />大多数服务器支持Hot deploy。你只需要在相应的Application目录Q具体\径依赖于服务
器)下面
建立一个符合WAR或EAR格式Q参见Q2.7QQ2.8Q的目录Q启动服务器Q就可以通过览?br />讉K了?br />特别的,你的Servlet的class文g应当攑֜/WEB-INF/classes目录中?br />注意J2EE SDK不支持Hot deployQ你需要通过它的deploy tool来部|Ӏ?br />Tomcat只支持WAR格式?/p>

Q2.6 EAR和WAR有什么不同?
{:EAR是一个完整的J2EE应用E序Q包括Web部分和EJB部分?br />WAR只是其中的Web部分?/p>

Q2.7 EAR格式是怎样的?
{:一个EAR可以包含L多个WAR或EJB JARQƈ且包含一个META-INF的目录?br />?META-INF中包含了一个application.xmlQ其中描qCq个EAR包含哪些模块Q以及安?br />性配|?br />l节L参考书?/p>

Q2.8 WAR格式是怎样的?
{:一个WAR包含一个WEB-INF的目录,q个目录下包含classes目录Qlib目录和web.xml?/p>

/WEB-INF/classes存放按packagel织的class文gQ?WEB-INF/lib目录存放jar文gQ?br />web.xml描述了很多东西,误参考书?/p>

Q2.9 我的普通HTML文g/JSP文g应当攑֜哪里Q?br />{:攑֜除了/WEB-INF以外的其他地斏V?/p>

感谢antegg|友对于安全性的提醒Q?br />如果你想直接?a href="http://url/***.jsp">http://url/***.jsp的方式来讉KQ就要像上面说得那样放?br />但是q样的做法是不安全的Q安全的做法是把所有的JSP面攑֜/WEB-INF目录下面Qƈ?/p>

通过WEB-CONTAINER来访问?/p>

作者意?
我更喜欢用filter来做安全性检查?br />在MVC模式中,JSP只是一个视图而已Q一般无需特别担忧安全性。和普通的html攑֜一?br />也利于维护?/p>

Q2.10 我访问不到servletQ甚臌HTML文g都访问不刎ͼ
{:
W一你没启动服务器?br />W二你敲错了端口?br />W三你没有正配|context-path?br />W四你的服务器不支持auto reload或者你关闭了这一选项Q你得重启服务器或重新部|W
AR?br />W五认你没有把HTML攑֜/WEB-INF目录下,那是讉K不到的?/p>

Q2.11 我能讉KHTML但是讉K不到servlet?br />{:h查你的web.xml文g。确保你正确定义?lt;servlet>?lt;servlet-mapping>元素?/p>

前者标识了一个servletQ后者将一个相对于context-path的URL映射C个servlet?br />在Tomcat中你可以通过/context-path/servlet/package/servletname的Ş式访问servlet
Q?br />但是q只是Tomcat的便捯问方式,q不是正式规范?br />l节L参考书?/p>

Q2.12  什么是JSPQ它和Servlet有什么区别?
{:你可以将JSP当做一个可扩充的HTML来对待?br />虽然在本质上JSP文g会被服务器自动翻译ؓ相应的Servlet来执行?br />可以说Servlet是面向JavaE序员而JSP是面向HTMLE序员的Q除此之外两者功能完全等?br />?/p>

Q2.13  我的JSP昄的汉字是q?br />{:在你的JSP开头加上一?<%@ page contentType="text/html; charset=gb18030"%>

如果你已l声明了page我想你知道该怎么修改?/p>

Q2.14  Z么用gb18030而不是gb2312Q?br />{:gb18030是gb2312之后的下一代汉字编码标准,最l将q渡到Unicode?/p>

Q2.15  在JSP里面怎么引用Java Bean?br />{:首先Q确认你要引用的cd/WEB-INF/classes下或?WEB-INF/lib的某个jar内?br />其次Q在JSP里加一?<jsp:useBean id="..." scope="..." class="..."/>
具体解释L参考书?/p>

Q2.16  我想在servlet间传递数据?br />{:利用session。在Servlet/JSP中,你可以在4个地方保存数据?br />1) pageQ本面?br />2) sessionQ用来存攑֮L关的信息Q比如购物RQ对应接口ؓjavax.servlet.http.H
ttpSession?br />session机制实际上是cookie和URL Rewriting的抽象,服务器会自动使用cookie或URL Re
writing来实现?br />3) requestQ可以在forward()时传递信息,对应接口为javax.servlet.http.HttpReques
t?br />4) applicationQ或UcontextQ存攑օ局信息Q对应接口ؓjavax.servlet.ServletCont
ext?/p>

Q2.17  怎么调用cookieQ?br />{:作者徏议用sessionQ你L会遇到某些禁用cookie的用戗这时session会自动
用URL重写来实现?/p>

Q2.18  怎么在JSP里面实现文g下蝲Q?br />{:实际上这是一个HTML的问题。答案是一个超链接<a>?/p>

Q2.19  怎么实现文g上传Q?br />{:客户端是HTML问题Q在form中设|method为postQenctype为multi-part/form-dataQ?br />加一?lt;input type="file">?br />而在接收的servlet中只是一个I/O问题Q你可以使用jakarta的file-upload库?/p>

Q2.20  我想让页面自动刷斎ͼ比如聊天室?br />{:q是一个HTML问题Q在<head>部分中加一?lt;meta http-equiv="refresh" content="
5" url="...">?br />q是所谓的Client-pullQ客Lh技术?br />相对的还有Server-pushQ服务器端刷新技术,但是q一技术由于要占用服务器端资源而会
在大量访问时出现瓉现象Q参?a >http://216.239.33.104/search?q=cache:autUfoakirY
J:www.kfunigraz.ac.at/edvndwww/books/books/javaenterprise/servlet/ch06_03.htm+
server-push+servlet&hl=zh-CN&ie=UTF-8

Q2.21  我想让用L录以后才能访问页面?br />{:使用声明式安全措施?br />你只需要在web.xml中定义安全角ԌRoleQ,q定义受保护的URL集合只能q定Role?br />问?br />大多数服务器支持Z数据库的用户映射Q你只要在相应数据库中徏立两张表q|服?br />器就可以了?br />注意J2EE SDK不支持基于数据库的用h?br />l节L参考书和服务器文?br />不过在商业环境中QJ2EE所提供的声明式安全措施仍然偏弱。一般商业程序会使用数据?br />存储user-role-privilege模型来达到安全性要求,l节误问你的构架设计师?/p>

Q2.22  我想要能注册用户?br />{:参看Q2.21。在接受注册h的Servlet中执行写入数据库操作卛_?/p>

Q2.23  怎么在JSP中访问数据库Q?br />{:标准做法是用DAO模式Q定义一个Java bean来访问数据库q在JSP中用?br />然而,当你的数据库模式很简单时Q你可以使用JSTL中的<sql:query>标签来快速访问?/p>

在一般的J2EE目中,JSP处于表示层(展现层)Q需要先后通过业务层和集成层才会访?br />到数据库Q所以这个问题确实只会在很小的程序中才会遇到?/p> Q2.24  什么是JSTLQ?br />{:JSTL是Jsp Standard Tag Library的羃写。这是一l通用标签q将成ؓJSP 2.0的一?br />分?br />其中包含赋?lt;c:set>Q分?lt;c:if>Q@?lt;c:forEach>Q查询数据库<sql:query>Q更新数
据库<sql:update>
{。目前你需要像d自定义标{ֺ一hdJSTLQ但是可以预计JSP 2.0会将JSTL作ؓ
l成部分?br />标签库可以在http://jakarta.apache.org下蝲。注意JSTL需要在支持JSP 1.2或更高版?br />的容器下q行?br />帮助文g可以阅读sun的JSTL正式规范

阿成 2006-08-16 14:43 发表评论
]]>
string和stringbuffer区别--转蝲邢红?的bloghttp://www.tkk7.com/ltc603/archive/2006/03/09/34555.html阿成阿成Thu, 09 Mar 2006 13:45:00 GMThttp://www.tkk7.com/ltc603/archive/2006/03/09/34555.htmlhttp://www.tkk7.com/ltc603/comments/34555.htmlhttp://www.tkk7.com/ltc603/archive/2006/03/09/34555.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/34555.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/34555.htmlq是好友面试的一道题Q其实我知道使用的区别,StringBuffer必须new出来QStringBuffer的append的效率比string?=的效率高Q?br />其实发现q有很大的区别,看了看以前scjp的考题
public class Test {
   public static void stringReplace (String text) {
   text = text.replace('j' , 'i');
   }
  
   public static void bufferReplace (StringBuffer text) {
   text = text.append("C");
   }
  
    public static void main (String args[]) {
    String textString = new String ("java");
    StringBuffer textBuffer = new StringBuffer ("java");
   
    stringReplace (textString);
    bufferReplace (textBuffer);
   
    System.out.println (textString + textBuffer);
    }
    }
{案?javajavaC
q是Java参数传?by value)造成?是不可变?immutable).,例如 基本cdQString传|复制了g递过去;可变的(ObjectQ传|复制了引用传递过厅R?

而题目中W七行text = text.append (“C?QappendҎ会改变text中的?br />而这个text与main中的textBuffer是指向同一个对象,所以对应的输出是javac?br />string的值永q不会改变!


String a = "a";//假设a指向地址0x0001Q?br />a = "b";//重新负值后a指向地址0x0002Q但0x0001地址中保存的"a"依旧存在Q但已经不再是a所指向的?br />从表面上看Stringcd的对象改变了|但事实是他不能改变|只能改变指向的地址


StringBuffer则不同,直接改变指向的地址中保留的?br />q有
StringBuffer s1 = new StringBuffer("a");
StringBuffer s2 = new StringBuffer("a");
s1.equals(s2)//Z么是false

String s1 = new String("a");
String s2 = new String("a");
s1.equals(s2)//Z么是true
StringBuffercM没有重新定义equalsq个ҎQ因此这个方法就来自Objectc,
而ObjectcM的equalsҎ是用来比较地址的,所以等于false.

StringcM重新定义了equalsq个ҎQ而且比较的是|而不是地址。所以会?br />true?br />对于q样能不能面试出真正的水qI感到怀疑?/p>

阿成 2006-03-09 21:45 发表评论
]]>
Java 初学http://www.tkk7.com/ltc603/archive/2006/02/07/29773.html阿成阿成Tue, 07 Feb 2006 03:29:00 GMThttp://www.tkk7.com/ltc603/archive/2006/02/07/29773.htmlhttp://www.tkk7.com/ltc603/comments/29773.htmlhttp://www.tkk7.com/ltc603/archive/2006/02/07/29773.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/29773.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/29773.html 、JDK,SDK,JRE,JVM

我们可以通过helloworld来理解这几个~写词的具体含义Q?br />

public class HelloWorld {
public static void main(String[] args) {
System.out.println("helloworld");
}
}



~译之后Q?我们得到了HelloWorld.classQ图中的"Your program's class files"Q?br />在HelloWorld里面Q?我们调用?JAVA API中的 java.lang.Systemq个cȝ静态成员对?out, out 的静态方? public static void println(String string);

然后我们让虚拟机器来执行q个HelloWorld?br />1. 虚拟Z在classpath中找到HelloWorld.class?br />2. 虚拟Z的解释器(interpret)会把HelloWorld.class解释成字节码?br />3. 把解释后的字节码交由execution engin执行?br />4. execution engin会调用native method(卛_^台相关的字节码)来在host system的stdout(昄?的指定部分打印出指定的字W串?br />5. q样Q?我们q?helloworld"字样了?br />
有了q个程后, 我们好理解上面几个术语了:
a. JDK: java develop kit (JAVA API?
b. SDK: software develop kit, 以前JDK 叫做java software develop kitQ?后来Z1.2版本后, 改名叫jdk了, 省时省力Q?节约成本?br />c. JRE. java runtime environment 我们的helloworld必须在JRE(JAVAq行环境,JAVAq行环境又叫JAVAq_Q里面, 才能跑v来?所以, 昄圎ͼ JRE其实是JDK + JVM

d. JVM java virtual machine. 单地Ԍ 是把class文g变成字节码, 然后送到excution engin中执行? 而ؓ什么叫虚拟机, 而不叫真实机呢? 因ؓJVM本n是又不能q算Q?又不能让昄器显C?helloworld"的, 它只能再调用host system的APIQ?比如在w32里面׃调c++的APIQ?来让CPU帮他做做术q算Q? 来调用c++里面的API来控制显C器昄昄字符丌Ӏ?而这些API不是JDK里面有的Q我们^时又看不见的Q所以我们就叫它native api了(亦曰U房XXQ?br />
e. 解释q_无关?有h会说Q?在linux的里面调用native api与w32里面调用的api肯定不一样吧Q?那ؓ什么说JAVA是^台无关的呢?
? 实是q样的, 君不见java.sun.com里面又有jdk-for-w32又有jdk-for-linux下蝲吗? 刚才不是说了吗? native api, native api, 是我们qx看不见的api吗! 调用nativeq些烦琐的活儉K让jdkd了? 所以我们调用的时候只用知道jdk(java api) 里面的java.io.*能提供磁盘访问功能, java.awt.* 能画个框框画个圆圆就行了吗?至于JDK又是怎么调用的, 在LINXU上更圆呢Q?q是在W32上更圆,(x) q个是JDK个h的事情了。(理论上讲是一样圆的, 当然q又和显C器是否U^相关?D)

同时Q?q里引甛_了另一个话题? 既如何编写^台无关的JAVAE序?其中关键的一条, 是调用且只调用jdk中的APIQ?而不要私自调用native api?原因很简单啊Q? JDK-for-linux和JDK-for-w32表面都是一LQ? 所以我在w32里面调用JDK写的javaE序Q在linux里面也会一L写法啊, 所以就可以UL来移植去都没问题?b) 但是如果我在w32里面调用?一个图形显C的native api, 当我UL到linuxȝ时候, 谁又能保证里面也有相同名Uͼ 相同参数Q相同返回| 相同功能的native api供我调用呢!(?)

-以上是个人理解, 如有错漏之处Q?万望指出Q?共同q步Q?/font>


2.Re:[入门]什么叫JDK,SDK,JRE,JVM [Re: sojan] Copy to clipboard
Posted by: reddream
Posted on: 2003-11-27 13:02

sojan wrote:
... 所以, 昄圎ͼ JRE其实是JDK + JVM...

q句话不寏VJRE֐思义只是java classq行旉要的环境QJDK不仅包含了JREQ还提供了开发调试javaE序需要的工具

3.Re:[入门]什么叫JDK,SDK,JRE,JVM [Re: sojan] Copy to clipboard
Posted by: sojan
Posted on: 2003-11-27 13:30

我将JREQJavaq行环境Q理解ؓJAVA PLATFORMQ?既JAVAq_?br />
reddream 的话也是对的Q?JRE同时也包括让JAVAq行h的工P比如Q?javacQ编译)Q?javaQ运行)Q?javapQ反~译Q这些?

另一角度

如果安装了JDKQ会发同你的电脑有两套JREQ一套位?jre 另外一套位?C:\Program Files\Java\j2re1.4.1_01 目录下,后面q套比前面那套少了Server端的Java虚拟机,不过直接前面那套的Server端Java虚拟机复制过来就行了。而且在安装JDK? 以选择是否安装q个位于 C:\Program Files\Jav a 目录下的JRE。如果你只安装JREQ而不是JDKQ那么只会在 C:\Program Files\Java 目录下安装唯一的一套JRE。?

    JRE的地位就象一台PCZP我们写好的Win32应用E序需要操作系l帮我们q行Q同LQ我们编写的JavaE序也必要JRE才能q行。所以当 你装完JDK后,如果分别在硬盘上的两个不同地方安装了两套JREQ那么你可以惌你的电脑有两台虚拟的Java PC机,都具有运行JavaE序的功能。所以我们可以说Q只要你的电脑安装了JREQ就可以正确q行Jav a应用E序?/p>

      1、ؓ什么Sun要让JDK安装两套相同的JREQ这是因为JDK里面有很多用Java所~写的开发工P如javac.exe、jar.exe{)Q而且都放|在 lib\tools.jar 里。从下面例子可以看出Q先tools.jar改名为tools1.jarQ然后运行javac.exeQ显C如下结果: Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac /Main q个意思是_你输入javac.exe与输?java -cp c:\jdk\lib\tools.jar com.sun.tools.javac.Main 是一LQ会得到相同的结果。从q里我们可以证明javac.exe只是一个包装器QWrapperQ,而制作的目的是ؓ了让开发者免于输入太长的指命? 而且可以发现lib目录下的E序都很,不大? 9KQ从q里我们可以得出一个结论。就是JDK里的工具几乎是用Java所~写Q所以也是Java应用E序Q因此要使用JDK所附的工具来开发JavaE? 序,也必要自行附一套JRE才行Q所以位于C:\Program Files\Java目录下的那套JRE是用来q行一般JavaE序用的?

     2、如果一台电脑安装两套以上的JREQ谁来决定呢Q这个重大Q务就落在java.exew上。Java.exe的工作就是找到合适的JRE来运? JavaE序?Java.exe依照底下的顺序来查找JREQ自q目录下有没有JREQ父目录有没有JREQ查询注册表Q? [HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment] 所以java.exe的运行结果与你的电脑里面哪个JRE被执行有很大的关pR?

    3、介lJVM JRE目录下的Bin目录有两个目录:server与client。这是真正的jvm.dll所在? jvm.dll无法单独工作Q当jvm.dll启动后,会用explicit的方法(是使用Win32 API之中的LoadLibrary()与GetProcAddress()来蝲入辅助用的动态链接库Q,而这些辅助用的动态链接库Q?dllQ都必须? 于jvm.dll所在目录的父目录之中。因此想使用哪个JVMQ只需要设|PATHQ指向JRE所在目录底下的jvm.dll?



对于q个pd里的问题Q每个学Java的h都应该搞懂。当Ӟ如果只是学Java玩玩无所谓了。如果你认ؓ自己已经越初学者了Q却不很懂这些问题,请将你自己重归初学者行列。内容均来自于CSDN的经典老脓?br />
二?/b>
java环境变量有三?/span>

JAVA_HOME,CLASSPATH,PATH.

只有q三?b style="color: black; background-color: rgb(255, 255, 102);">java环境变量?/font>

JAVA_HOME指向的是JDK的安装\径,如C:\j2sdk1.4.2_09Q在q\径下你应该能够找到bin、lib{目录。当Ӟ你愿意放哪里Q就攑֓里。我的是攑֜c盘根目录

JAVA_HOME=C:\j2sdk1.4.2_09;

PATH环境变量,目的是ؓ了指向JDK的bin目录Q这里面攄是各U编译执行命令?/font>

我的讄是:

PATH=C:\j2sdk1.4.2_09\bin;C:\j2sdk1.4.2_09\jre\bin;

需要说明,pȝ中本w就有PATH环境变量Q只要把C:\j2sdk1.4.2_09\bin;C:\j2sdk1.4.2_09\jre\bin;直接攑ֈ后面卛_Q中间有分号间隔?/font>

如果你的JAVA_HOME是别的目录,对照着该吧?/font>

CLASSPATH最重要?/font>

CLASSPATH=.;C:\j2sdk1.4.2_09\lib;C:\j2sdk1.4.2_09\lib\tools.jar;q时我的讄。这是类的\径。前面加上点和分P意ؓ首先在当前目录查找,以后你自q写类的时候自然明白这炏V?/font>

那么Z么要讄环境变量Q以前编写c语言的时候怎么不设|呢Q?/font>

׃WINDOWS默认的搜索顺序,先搜索当前目录的Q再搜烦pȝ目录的,再搜索PATH环境变量讑֮的。你在编?b style="color: black; background-color: rgb(255, 255, 102);">javaE序Ӟ在一个指定目录,q里没有~译执行命oQ而系l目录里面,也没有编译执行命令。所以放?b style="color: black; background-color: rgb(160, 255, 255);">环境变量里面Q?从这里你应该可以看出Q?b style="color: black; background-color: rgb(160, 255, 255);">环境变量是干什么用的了。简单说是告诉操作pȝ到那里去找指定的文g。你要是把系l目录给改了Q看你用dos命oq好不好ѝ?/font>

配置完后Q在命o提示W下Q键?b style="color: black; background-color: rgb(255, 255, 102);">java -version,如果出现java的一些信息,说明配置成功

//问题一
在命令行中输?javac HelloWorld.java 后出现如下错误:
′javac?不是内部或外部命令,也不是可q行的程序或批处理文件?
(javac: Command not found)

q个错误产生的原因是没有讄?b style="color: black; background-color: rgb(160, 255, 255);">环境变量path。下面以windows xpZ子来讲解如何讄环境变量path。右键单L的电脑->属性->高Q?gt;环境变量Q然后在pȝ变量中选择dQ变量名为pathQ变量gؓd:\j2se\binQ这里假设你的jdk的安装d:\j2se,当然如果你的jdk的安装目录是别的目录的话Q比如c:\jdk1.2Q那么你的path应该讄?strong>c:\jdk1.2\bin。)。最后不要忘C重新启动Q当然你也可以再接着讄完另一?b style="color: black; background-color: rgb(160, 255, 255);">环境变量classpath后再重新启动?/p>

//问题?br />在命令行中输?java HelloWorld 后出现如下错Q注意不?java HelloWorld.class 。)

Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld

q个错误产生的原因是没有讄?b style="color: black; background-color: rgb(160, 255, 255);">环境变量classpathQ这时只需要将classpath的D|ؓ
.;d:\j2se\lib\dt.jar;d:\j2se\lib\tools.jar
当然Q如果你的jdk的安装目录是在别的地方的话,比如c:\jdk1.2Q那么你的classpath变量应该讄?br />.;c:\jdk1.2\lib\dt.jar;c:\jdk1.2\lib\tools.jar
最后重新启动,然后再小心:Q的ȝ译你的HelloWorld.javaE序


三、基知识


问题一Q?/b>我声明了什么!

String s = "Hello world!";

许多人都做过q样的事情,但是Q我们到底声明了什么?回答通常是:一个StringQ内Ҏ“Hello world!”。这hp的回答通常是概念不清的Ҏ。如果要准确的回{,一半的人大概会回答错误?br />q个语句声明的是一个指向对象的引用Q名为“s”,可以指向cd为String的Q何对象,目前指向"Hello world!"q个Stringcd的对象。这是真正发生的事情。我们ƈ没有声明一个String对象Q我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:

String string = s;

我们是声明了另外一个只能指向String对象的引用,名ؓstringQƈ没有W二个对象生,stringq是指向原来那个对象Q也是Q和s指向同一个对象?br />
问题二:"=="和equalsҎI竟有什么区别?

==操作W专门用来比较变量的值是否相{。比较好理解的一ҎQ?br />int a=10;
int b=10;
则a==b是true?br />但不好理解的地方是:
String a=new String("foo");
String b=new String("foo");
则a==b返回false?br />
Ҏ前一帖说q,对象变量其实是一个引用,它们的值是指向对象所在的内存地址Q而不是对象本w。a和b都用了new操作W,意味着在内存中生两个内容ؓ"foo"的字W串Q既然是“两个”,它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的|所以?=="操作W,l果会是false。诚Ӟa和b所指的对象Q它们的内容都是"foo"Q应该是“相{”,但是==操作Wƈ不涉及到对象内容的比较?br />对象内容的比较,正是equalsҎ做的事?br />
看一下Object对象的equalsҎ是如何实现的Q?br />boolean equals(Object o){

return this==o;

}
Object对象默认使用?=操作W。所以如果你自创的类没有覆盖equalsҎQ那你的cM用equals和?=会得到同Ll果。同样也可以看出QObject的equalsҎ没有辑ֈequalsҎ应该辑ֈ的目标:比较两个对象内容是否相等。因为答案应该由cȝ创徏者决定,所以Object把这个Q务留l了cȝ创徏者?br />
看一下一个极端的c:
Class Monster{
private String content;
...
boolean equals(Object another){ return true;}

}
我覆盖了equalsҎ。这个实CD无论Monster实例内容如何Q它们之间的比较永远q回true?br />
所以当你是用equalsҎ判断对象的内Ҏ否相{,请不要想当然。因为可能你认ؓ相等Q而这个类的作者不q样认ؓQ而类的equalsҎ的实现是׃掌握的。如果你需要用equalsҎQ或者用Q何基于散列码的集合(HashSet,HashMap,HashTableQ,请察看一下java doc以确认这个类的equals逻辑是如何实现的?br />
问题三:String到底变了没有Q?/font>

没有。因为String被设计成不可?immutable)c,所以它的所有对象都是不可变对象。请看下列代码:

String s = "Hello";
s = s + " world!";

s所指向的对象是否改变了呢?从本pdW一的l论很容易导个结论。我们来看看发生了什么事情。在q段代码中,s原先指向一个String对象Q内Ҏ"Hello"Q然后我们对sq行?操作Q那么s所指向的那个对象是否发生了改变呢?{案是没有。这Ӟs不指向原来那个对象了Q而指向了另一个String对象Q内容ؓ"Hello world!"Q原来那个对象还存在于内存之中,只是sq个引用变量不再指向它了?br />通过上面的说明,我们很容易导出另一个结论,如果l常对字W串q行各种各样的修改,或者说Q不可预见的修改Q那么用String来代表字W串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符Ԍ都需要一个String对象来表C。这Ӟ应该考虑使用StringBufferc,它允怿改,而不是每个不同的字符串都要生成一个新的对象。ƈ且,q两U类的对象{换十分容易?br />同时Q我们还可以知道Q如果要使用内容相同的字W串Q不必每ơ都new一个String。例如我们要在构造器中对一个名叫s的String引用变量q行初始化,把它讄为初始|应当q样做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
后者每ơ都会调用构造器Q生成新对象Q性能低下且内存开销大,q且没有意义Q因为String对象不可改变Q所以对于内容相同的字符Ԍ只要一个String对象来表C就可以了。也pQ多ơ调用上面的构造器创徏多个对象Q他们的Stringcd属性s都指向同一个对象?br />上面的结Zq样一个事实:对于字符串常量,如果内容相同QJava认ؓ它们代表同一个String对象。而用关键字new调用构造器QL会创Z个新的对象,无论内容是否相同?br />至于Z么要把Stringc设计成不可变类Q是它的用途决定的。其实不只StringQ很多Java标准cd中的c都是不可变的。在开发一个系l的时候,我们有时候也需要设计不可变c,来传递一l相关的|q也是面向对象思想的体现。不可变cL一些优点,比如因ؓ它的对象是只ȝQ所以多U程q发讉K也不会有M问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表Q可能会造成性能上的问题。所以Java标准cdq提供了一个可变版本,即StringBuffer?br />
问题四:final关键字到底修C什么?

final使得被修饰的变量"不变"Q但是由于对象型变量的本质是“引用”,使得“不变”也有了两种含义Q引用本w的不变Q和引用指向的对象不变?br />
引用本n的不变:
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;//~译期错?br />
引用指向的对象不变:
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!"); //~译通过

可见Qfinal只对引用的“值?也即它所指向的那个对象的内存地址)有效Q它q引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化Qfinal是不负责的。这很类?=操作W:==操作W只负责引用的“值”相{,至于q个地址所指向的对象内Ҏ否相{,==操作W是不管的?br />
理解final问题有很重要的含义。许多程序漏z都Z?---final只能保证引用永远指向固定对象Q不能保证那个对象的状态不变。在多线E的操作?一个对象会被多个线E共享或修改Q一个线E对对象无意识的修改可能会导致另一个用此对象的线E崩溃。一个错误的解决Ҏ是在此对象新徏的时候把它声明ؓfinalQ意图得它“永q不变”。其实那是徒劳的?br />
问题五:到底要怎么样初始化Q?/font>

本问题讨论变量的初始化,所以先来看一下Java中有哪些U类的变量?br />1. cȝ属性,或者叫值域
2. Ҏ里的局部变?br />3. Ҏ的参?br />
对于W一U变量,Java虚拟Z自动q行初始化。如果给Z初始|则初始化初始倹{如果没有给出,则把它初始化cd变量的默认初始倹{?br />
intcd变量默认初始gؓ0
floatcd变量默认初始gؓ0.0f
doublecd变量默认初始gؓ0.0
booleancd变量默认初始gؓfalse
charcd变量默认初始gؓ0(ASCII?
longcd变量默认初始gؓ0
所有对象引用类型变量默认初始gؓnullQ即不指向Q何对象。注意数l本w也是对象,所以没有初始化的数l引用在自动初始化后其g是null?br />
对于两种不同的类属性,static属性与instance属性,初始化的时机是不同的。instance属性在创徏实例的时候初始化Qstatic属性在cd载,也就是第一ơ用到这个类的时候初始化Q对于后来的实例的创建,不再ơ进行初始化。这个问题会在以后的pd中进行详l讨论?br />
对于W二U变量,必须明确地进行初始化。如果再没有初始化之前就试图使用它,~译器会抗议。如果初始化的语句在try块中或if块中Q也必须要让它在W一ơ用前一定能够得到赋倹{也是_把初始化语句攑֜只有if块的条g判断语句中编译器也会抗议Q因为执行的时候可能不W合if后面的判断条Ӟ如此一来初始化语句׃会被执行了,q就q反了局部变量用前必须初始化的规定。但如果在else块中也有初始化语句,可以通过~译Q因为无论如何,L臛_一条初始化语句会被执行Q不会发生用前未被初始化的事情。对于try-catch也是一P如果只有在try块里才有初始化语句,~译部通过。如果在catch或finally里也有,则可以通过~译。MQ要保证局部变量在使用之前一定被初始化了。所以,一个好的做法是在声明他们的时候就初始化他们,如果不知道要Z化成什么值好Q就用上面的默认值吧Q?br />
其实W三U变量和W二U本质上是一LQ都是方法中的局部变量。只不过作ؓ参数Q肯定是被初始化q的Q传入的值就是初始|所以不需要初始化?br />
问题六:instanceof是什么东东?

instanceof是Java的一个二元操作符Q和==Q?gt;Q?lt;是同一cM东。由于它是由字母l成的,所以也是Java的保留关键字。它的作用是试它左边的对象是否是它双的类的实例,q回booleancd的数据。D个例子:

String s = "I AM an Object!";
boolean isObject = s instanceof Object;

我们声明了一个String对象引用Q指向一个String对象Q然后用instancof来测试它所指向的对象是否是Objectcȝ一个实例,昄Q这是真的,所以返回trueQ也是isObject的gؓTrue?br />instanceof有一些用处。比如我们写了一个处理̎单的pȝQ其中有q样三个c:

public class Bill {//省略l节}
public class PhoneBill extends Bill {//省略l节}
public class GasBill extends Bill {//省略l节}

在处理程序里有一个方法,接受一个Billcd的对象,计算金额。假设两U̎单计方法不同,而传入的Bill对象可能是两U中的Q何一U,所以要用instanceof来判断:

public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {
//计算电话账单
}
if (bill instanceof GasBill) {
//计算燃气账单
}
...
}
q样可以用一个方法处理两U子cR?br />
然而,q种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实玎ͼq是面向对象变成应有的做法,避免回到l构化编E模式。只要提供两个名字和q回值都相同Q接受参数类型不同的Ҏ可以了Q?br />
public double calculate(PhoneBill bill) {
//计算电话账单
}

public double calculate(GasBill bill) {
//计算燃气账单
}

所以,使用instanceof在绝大多数情况下q不是推荐的做法Q应当好好利用多态?



阿成 2006-02-07 11:29 发表评论
]]>
JavaMailAPI?/title><link>http://www.tkk7.com/ltc603/archive/2006/01/24/29111.html</link><dc:creator>阿成</dc:creator><author>阿成</author><pubDate>Tue, 24 Jan 2006 07:14:00 GMT</pubDate><guid>http://www.tkk7.com/ltc603/archive/2006/01/24/29111.html</guid><wfw:comment>http://www.tkk7.com/ltc603/comments/29111.html</wfw:comment><comments>http://www.tkk7.com/ltc603/archive/2006/01/24/29111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/ltc603/comments/commentRss/29111.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/ltc603/services/trackbacks/29111.html</trackback:ping><description><![CDATA[ <table align="left" border="0"> <tbody> <tr> <td> </td> </tr> </tbody> </table> <a class="wordstyle" target="_blank"> <font color="#246398">Java</font> </a>Mail API?br /><a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API是一U可选的、能用于d、编写和发送电子消息的包(标准扩展Q。您可用这U包创徏邮g用户代理QMail User Agent QMUAQ?cd?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>Q它cM于Eudora、Pine及Microsoft Outlookq些邮g<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>。其主要目的不是像发送邮件或其他邮g传输代理QMail Transfer AgentQMTAQ类型的<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>那样用于传输、发送和转发消息。换句话_用户可以与MUAcd?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>交互Q以阅读和撰写电子邮件。MUA依靠MTA处理实际的发送Q务?br /><a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的设计是Qؓ收发信息提供与协议无关的讉K。方式是把该API划分成两个部分:<br />· 该API的第一个部分是本课E的重点。基本上是如何发送和接收独立于提?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>/协议的消息?br />· W二个部分则使用特定的协议语aQ如QSMTP、POP、IMAP和NNTP。如果要?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API与服务器通信Q就需要ؓ之提供协议。由于Sun公司对特定协议提?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>有充分的介绍Q用户可以免费获取,所以本评没有介绍创徏特定协议提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>的内宏V?br />复习相关协议<br />在学?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的深层知识之前,让我们回q头来看一看在该API中用的协议,本质上有4Uh们常用的协议Q?br />· SMTP<br />· POP<br />· IMAP<br />· MIME<br />您还需要了解NNTP及其他一些协议。理解这些协议的基本原理有助于您理解如何使用<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API。而该API的设计要与协议无养I所以不能克服这些基协议的限制。如果选用的协议不支持某种功能Q那?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API也无法在其上dq种功能。(正如您一会儿׃看到的,在操作POP协议Ӟ常常会碰到这U问题)?br />SMTP<br />单邮件传输协议(SMTPQ是用于传送电子邮件的机制。在<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API环境中,您的Z<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>与您公司或Internet服务提供商(ISPQ的SMTP服务器通信。该SMTP服务器将会把消息转发l用作接收消息的SMTP服务器,最后用户可通过POP或IMAP协议获取该消息。由于支持n份验证,所以不需要SMTP服务器是一U开攄转发器,但需要确保SMTP服务器配|正?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API中没有集成用于处理诸如配|服务器以{发消息或d/删除电子邮g帐户q一cMQ务的功能?br />POP<br />POP的含义是邮局协议Q当前的版本?Q也UCPOP3Q该协议是在RFC 1939中定义的。POP是Internet上的大多Ch用来接收邮g的机制。它为每个用L每个邮箱定义支持Q这是它所做的全部工作Q也是大多数问题的根源。在使用POP协议ӞZ熟悉的很多功能,如查看收C多少新邮件消息的功能QPOPҎ不支持。这些功能都内置到诸如Eudora或Microsoft Outlook之类的邮?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>中,能ؓ您记住接收的上一邮Ӟ以及计算有多新邮gq类信息。因此,使用<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail APIӞ如果惌取这cM息,需要由自己q行计算?br />IMAP<br />IMAP是用于接收消息的更加高的协议,它是在RFC 2060中定义的。IMAP的含义是“Internet消息讉K协议”,当前版本是第4版,也称作IMAP4。用IMAPӞ您的邮g服务器必L持该协议。您不能只是单地?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>转变为支持IMAPQ而不是支持POPQ就指望能支持IMAP中的一切。假定您的邮件服务器支持IMAPQ那么基?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>可利用在服务器上拥有多个文件夹的用Pq且q些文g夹可以被多个用户׃n的功能?br />׃IMAP协议h更高U的功能Q您也许会想IMAP应该被每一个h使用Q但事实不是q样。因为IMAP会加重邮件服务器的负P它需要服务器接收新消息,发送消息给h的用Pq在多个文g夹中为每个用L护这些消息。而这要集中备份,因而长期下ȝL文g夹会变得来大Q当盘I间用光了时Q每个h都会遭受损失。而用POP协议Ӟ已保存消息可以解除服务器的重负?br />MIME<br />MIME的含义是“多用途的|际邮g扩充协议”。它不是一U邮件传输协议,相反Q它定义传输的内容:消息的格式、附件等。许多文都定义了MIME协议Q包含:RFC 822、RFC 2045、RFC 2046和RFC 2047。作?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的用P一般不需要担心这些格式。但是,q些格式实存在Qƈ为您?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>所用?br />NNP和其他协?br />׃<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API分开了提?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>和其他部分,所以您可以LCؓ附加协议d支持。Sun公司提供W?Ҏ?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>清单Q这些提?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>要利?Sun公司不支持的见的协议。在q䆾清单中,您将会看到对NNTPQ?a class="wordstyle" target="_blank"><font color="#246398">|络</font></a>新闻传输协议Q[新闻l]、S/MIMEQ安全多用途的|际邮g扩充协议Q及其他协议的提供支持的W?Ҏ?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>?br />安装<br />目前有两U版本的<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API最常用Q?.2?.1.3。本评中的所有例子都适用于这两种版本。其?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API 1.2是最新的Q?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API 1.1.3中包含了<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a> 2企业版(J2EEQ^?.2.1版,所以它仍然很常用。?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的版本会Ҏ的下载和安装产生一些媄响。这两种版本?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API都能与JDK 1.1.6?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a> 2标准版(J2SEQ^?.2.x?.3.x协同工作?br />注意Q在安装了Sun公司?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail工具后,会在演示目录下看到许多示?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>?br />安装<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.2<br />要?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.2 APIQ可以下?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.2工具Q然后解压羃<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>mail-1_2.zip文gQƈ把mail.jar文gd到典型安装\径下?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.2工具带有SMTP、IMAP4和POP3提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>以及核心cR?br />安装?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.2后,再安?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Beans Activation Framework?br />安装<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3<br />要?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3 APIQ可以下?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3工具Q然后解压羃<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>mail1_1_3.zip文gQƈ把mail.jar文gd到典型安装\径下?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3工具带有SMTP和IMAP4提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>以及核心cR?br />如果您想?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3讉KPOP服务器,需要下载ƈ安装POP3提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>。Sun公司拥有一个独立于 <a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 工具的提?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>。在下蝲q解压羃pop31_1_1.zip文g后,也还需要把pop3.jard到典型安装\径下?br />安装?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3后,再安?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Beans Activation Framework?br />安装<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Beans Activation Framework<br /><a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的所有版本都需?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Beans Activation FrameworkQ?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>BeansȀzLӞQ这U框架提供了对输入Q意数据块的支持,q能相应地对其进行处理。看上去效果好像不太好,但该框架是在当今的许多浏览器和邮件工具中可以扑ֈ的基本MIMEcd支持。下载该框架后,解压~jaf1_0_1.zip文gQƈactivation.jar文gd到典型安装\径下?br />对于<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.2用户Q现在应该把mail.jar和activation.jar文gd到典型安装\径下?br />对于<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3用户Q现在应该把mail.jar、pop3.jar和activation.jard到典型安装\径下。如果您不打用POP3Q就不需要把pop3.jar文gd到典型安装\径下?br />如果您不x改安装\径环境变量,可以把JAR文g复制?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>q行时环境(JREQ目录下的lib/ext目录下。例如,对于J2SE 1.3版本Q?a class="wordstyle" target="_blank"><font color="#246398">Windows</font></a>q_上的默认目录应该是C:\jdk1.3\jre\lib\ext?br />使用<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a> 2企业?br />如果您用的是J2EEQ则在用基?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail APIӞ不需要做什么特D的工作Q?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API带有J2EEcR只要确保j2ee.jar文g位于典型安装路径下,q完成了所有的讄工作?<br />对于J2EE 1.2.1QPOP3提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>是单独提供的Q因此需要下载该提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>Qƈ按安?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 1.1.3的步骤,在J2EE 1.2.1中包含POP3提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>。J2EE 1.3的用户会获得J2EE和POP3提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>Q因而不需要对POP3提供<a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>执行独立安装。用这两种版本的J2EE用户Q都不需要安?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Beans Activation Framework?br />l习<br />讄您的 <a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail 环境?br />复习核心c?br />在开始深入研I?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>MailcM前,首先让用h览一下构成API的核心类Q会话、消息、地址、验?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>、传输,存储和文件夹。所有这些类都可以在<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API?a class="wordstyle" target="_blank"><font color="#246398">java</font></a>x.mail的顶层包中找刎ͼ管您将频繁地发现您自己使用的子cL?a class="wordstyle" target="_blank"><font color="#246398">java</font></a>x.mail.internet包中扑ֈ的?br />Sessionc?br />Sessioncd义了一个基本的邮g会话。通过该会话可让别的工作顺利执行。Session对象利用<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>.util.Properties对象获取诸如邮g服务器、用户名、密码等信息Q以及其他可在整个应?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>中共享的信息?br />Sessioncȝ构造器是私有的。您可以获得一个可被getDefaultInstance()Ҏ׃n的单一的默认会话:<br />Properties props = new Properties();<br />// fill props with any information<br />Session session = Session.getDefaultInstance(props, null);<br />或者,您可以用getInstance()Ҏ创徏一个独特的会话Q?br />Properties props = new Properties();<br />// fill props with any information<br />Session session = Session.getInstance(props, null);<br />q两U情形下的null参数都是一UAuthenticator对象Q它不是在此时用的。详l信息请参阅其后的“Autherticator”一节?br />在大多数情况下,使用׃n会话p够了Q即使ؓ多个用户邮箱处理邮g会话也是如此。您可以在通信q程的后面一步添加上用户名和密码的组合,q保持所有的一切是独立的?br />Messagec?br />一旦创Z自己的Session对象Q就是该d发送的消息的时候了。这时就要用到消息类型。作Z个抽象类Q您必须操作一个子c,在大多数情况下,该子cL<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>x.mail.internet.MimeMessage。一个MimeMessage是一U理解MIMEcd和报_在不同的RFC文中均有定义)的消息。消息的报头被严格限制成只能使用US-ASCII字符Q尽非ASCII字符可以被编码到某些报头字段中?br />可以通过Session对象传递给MimeMessage构造器的方法来创徏消息Q?br />MimeMessage message = new MimeMessage(session);<br />注意Q还有其他的构造器Q像用于创徏消息的源于RFC822格式化的输入的构造器?br />一旦创Z消息Q就可以讄其各个部分,如Message(消息)实现PartQ部分)接口Q以MimeMessage实现MimePartQ。设|内容的基本机制是setContent()ҎQ它带有表示内容和MIMEcd的参敎ͼ<br />message.setContent("Hello", "text/plain");<br />但是Q如果正在?MimeMessageQƈ且您的消息是U文本,那么您就可以使用setText()Ҏ。该Ҏ只需要一个表C实际内容的参数Q默认的MIMEcd为纯文本Q?br />message.setText("Hello");<br />对于U文本消息,setText()Ҏ更常常被用来讄内容。要发送其他类型的消息Q如HTML消息Q就要用setContentҎ()。现在用的更多的是HTML消息?br />要设|主题,可以使用setSubject()ҎQ?br />message.setSubject("First");<br />Addressc?br />一旦创Z会话和消息,qؓ消息填充了内容,需要用AddresscMؓ您的信g标上地址了。同MessagecMPAddresscM是一U抽象类。您可以使用<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>x.mail.internet.InternetAddresscR?br />要创建只带有电子邮g地址的地址Q可以把电子邮g地址传递给Addresscȝ构造器Q?br />Address address = new InternetAddress("<a href="mailto:president@whitehouse.gov"><font color="#246398">president@whitehouse.gov</font></a>");<br />如果惌一个名字出现在电子邮g地址后,也可以将其传递给构造器Q?br />Address address = new InternetAddress("<a href="mailto:president@whitehouse.gov"><font color="#246398">president@whitehouse.gov</font></a>", "George Bush");<br />您要为消息的fromQ发送者)字段和toQ接收者)字段创徏地址对象。除非您的邮件服务器Lq样做,否则要在发送的消息中注明该消息的发送者?br />一旦创建好了地址Q有两种Ҏ可让您将地址与消息连接v来。ؓ了鉴别发送者,您可以用setFrom()和setReplyTo()Ҏ?br />message.setFrom(address)<br />如果您的消息需要显C多个地址来源Q则可以使用addFrom()ҎQ?br />Address address[] = ...;<br />message.addFrom(address);<br />Z鉴别消息接收者,您可以用addRecipient()Ҏ。该Ҏ除了需要一个地址参数外,q需要一个Message.RecipientType属性(消息的接收类型)?br />message.addRecipient(type, address)<br />地址?U预定义cd如下Q?br />· Message.RecipientType.TO <br />· Message.RecipientType.CC <br />· Message.RecipientType.BCC <br />因此Q如果一条消息将发送给副ȝQ同时还发送该消息的副本给W一夫hQ则采用下面的代码:<br />Address toAddress = new InternetAddress("<a href="mailto:vice.president@whitehouse.gov"><font color="#246398">vice.president@whitehouse.gov</font></a>");<br />Address ccAddress = new InternetAddress("<a href="mailto:first.lady@whitehouse.gov"><font color="#246398">first.lady@whitehouse.gov</font></a>");<br />message.addRecipient(Message.RecipientType.TO, toAddress);<br />message.addRecipient(Message.RecipientType.CC, ccAddress);<br /><a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API没有提供查电子邮件地址有效性的机制。您可以自己~写支持扫描有效字符Q在RFC 822文中所定义的)?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>或检验MXQ邮件交换)记录Q这些都越?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的范围?br />Authenticatorc?br />?a class="wordstyle" target="_blank"><font color="#246398">java</font></a>.netcMP<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API可以利用AuthenticatorQ验?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>Q类通过用户名和密码来访问受保护的资源。对?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API来说Q这U受保护的资源是指邮件服务器?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail的Authenticatorcd以在<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>x.mail包中扑ֈQƈ有别于同名的<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>.netcR当<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a> 1.1下工作时Q?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail?a class="wordstyle" target="_blank"><font color="#246398">java</font></a>.net不会׃n同一个AuthenticatorcdUͼq是因ؓ<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a> 1.1中不含有<a class="wordstyle" target="_blank"><font color="#246398">java</font></a>.net?br />要用Authenticatorc,您可以用该抽象cȝ子类Qƈ通过getPasswordAuthentication()Ҏq回一个PasswordAuthentication实例。在创徏Ӟ您必ȝ会话记录AuthenticationcR其后,当需要进行n份验证时Q会通知您的Authenticator。会弹出一个窗口,或从一个配|文Ӟ管不加密就不安全)中读取用户名和密码,q把它们作ؓ一个PasswordAuthentication对象q回l调?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>?br />Properties props = new Properties();<br />// fill props with any information<br />Authenticator auth = new MyAuthenticator();<br />Session session = Session.getDefaultInstance(props, auth);<br />Transportc?br />发送消息的最后一步操作是使用TransportcR该cM用特定于协议Q通常是SMTPQ的语言来发送消息。它是一个抽象类Q其操作与SessioncL些相伹{您可以通过只调用静态的send()Ҏ来用该cȝ默认版本Q?br />Transport.send(message);<br />或者,您可以从用于您的协议的会话中获取一个特定的实例Q然后传递用户名和密码(不必要时可以为空Qƈ发送消息,最后关闭连接:<br />message.saveChanges(); // implicit with send()<br />Transport transport = session.getTransport("smtp");<br />transport.connect(host, username, password);<br />transport.sendMessage(message, message.getAllRecipients());<br />transport.close();<br />当您需要发送多个消息时Q徏议采用后一U方法,因ؓ它将保持消息间活动服务器的连接。而基本的send()机制会ؓ每一个方法调用都建立一条独立的q接?br />注意Q要查看l过邮g服务器邮件命令,可以用session.setDebug(true)Ҏ讄调试标志?br />Store和Folderc?br />使用SessioncL获取消息Q开始时与发送消息很怼。但是,在获取会话后Q很有可能用用户名和密码或AuthenticatorcLq接StorecR与TransportcMP您要告诉Storecd使用什么协议:<br />// Store store = session.getStore("imap");<br />Store store = session.getStore("pop3");<br />store.connect(host, username, password);<br />在连接StorecdQ就可以获取一个Folderc,在读取其中的消息前必d打开该类?br />Folder folder = store.getFolder("INBOX");<br />folder.open(Folder.READ_ONLY);<br />Message message[] = folder.getMessages();<br />对于POP3协议Q惟一可用的文件夹是INBOX。如果用的是IMAP协议Q则可以使用其他的文件夹?br />注意QSun公司的提?a class="wordstyle" target="_blank"><font color="#246398">E序</font></a>本来x供方ѝ而Message message[]=folder.getMessages();q条语句却是一U从服务器逐条d消息的缓慢操作,所以仅当您实需要获取消息部分(该内Ҏ所索消息的内容Q时可以使用q条语句?br />一旦读取消息,可以用getContent()Ҏ获取其内容,或用writeTo()Ҏ其内容写到一个流中。getContent()Ҏ只获取消息内容,而writeTo()Ҏ则还会输出报头?br />System.out.println(((MimeMessage)message).getContent());<br />一旦您阅读完邮Ӟ可以关闭对文g夹和存储的连接?br />folder.close(aBoolean);<br />store.close();<br />传递给文g夹的close()Ҏ的布变量指定了是否通过清除已删除的消息来更新文件夹?br />l箋前进<br />实际上,理解使用q?个类的方式,是?a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API处理几乎所有事情所需要的全部内容。用q?个类以外的方式构建的<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail APIQ其大多数功能都是以几乎完全相同或特定的方式来执行Q务的Q就好像内容是附件。特定的dQ如Q搜索、隔ȝ在后面q行介绍?br />使用<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API<br />您已l看C如何操作<a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail API的核心部分。在下面几节中,您将学习如何q接几个部分以执行特定的d?br />发送消?br />发送电子邮件消息涉及到获取会话、创建和填充消息q发送消息这些操作。您可以在获取SessionӞ通过传递的Properties对象讄mail.smtp.host属性来指定您的SMTP服务器?br />String host = ...;<br />String from = ...;<br />String to = ...;<br />// Get system properties<br />Properties props = System.getProperties();<br />// Setup mail server<br />props.put("mail.smtp.host", host);<br />// Get session<br />Session session = Session.getDefaultInstance(props, null);<br />// Define message<br />MimeMessage message = new MimeMessage(session);<br />message.setFrom(new InternetAddress(from));<br />message.addRecipient(Message.RecipientType.TO, <br />new InternetAddress(to));<br />message.setSubject("Hello <a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail");<br />message.setText("Welcome to <a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail");<br />// Send message<br />Transport.send(message);<br />您应该在try-catch块中~写代码Q以在创建消息ƈ发送它时可以抛Z个异常?br />l习<br />发送您的第一个消?br />获取消息<br />对于阅读邮g来说Q首先您要获取一个会话,然后获取q连接到一个相应的用于您的收gq存储上,接着打开相应的文件夹Q再获取消息。同Ӟ不要忘记了操作完成后关闭q接?br />String host = ...;<br />String username = ...;<br />String password = ...;<br />// Create empty properties<br />Properties props = new Properties();<br />// Get session<br />Session session = Session.getDefaultInstance(props, null);<br />// Get the store<br />Store store = session.getStore("pop3");<br />store.connect(host, username, password);<br />// Get folder<br />Folder folder = store.getFolder("INBOX");<br />folder.open(Folder.READ_ONLY);<br />// Get directory<br />Message message[] = folder.getMessages();<br />for (int i=0, n=message.length; i<n; i++) {<br />System.out.println(i + ": " + message[i].getFrom()[0] <br />+ "\t" + message[i].getSubject());<br />}<br />// Close connection <br />folder.close(false);<br />store.close();<br />每一条消息执行何U操作取决于自己军_。上面的代码块只是显CZ消息的发送者和主题。从<a class="wordstyle" target="_blank"><font color="#246398">技?/font></a>上讲Q发送者地址列表可以为空Q此时getFrom()[0]调用会抛Z个异常?br />Z昄整条消息Q您可以提示用户在看完消息的发送者和主题字段后,如果想看到消息的内容Q可以再调用消息的writeTo()Ҏ?br />BufferedReader reader = new BufferedReader (<br />new InputStreamReader(System.in));<br />// Get directory<br />Message message[] = folder.getMessages();<br />for (int i=0, n=message.length; i<n; i++) {<br />System.out.println(i + ": " + message[i].getFrom()[0] <br />+ "\t" + message[i].getSubject());<br />System.out.println("Do you want to read message? " +<br />"[YES to read/QUIT to end]");<br />String line = reader.readLine();<br />if ("YES".equals(line)) {<br />message[i].writeTo(System.out);<br />} else if ("QUIT".equals(line)) {<br />break;<br />}<br />}<br /><br /><br />发送附?br />MimeMessage message = <br />         new MimeMessage(session);<br />      message.setFrom(<br />         new InternetAddress(from));<br />      message.addRecipient(<br />         Message.RecipientType.TO, <br />         new InternetAddress(to));<br />      message.setSubject(<br />         "Hello <a class="wordstyle" target="_blank"><font color="#246398">Java</font></a>Mail Attachment");<br /><br />      // create the message part <br />MimeBodyPart messageBodyPart = <br />         new MimeBodyPart();<br /><br />      //fill message<br />      messageBodyPart.setText("Hi");<br /><br />      Multipart multipart = new MimeMultipart();<br />      multipart.addBodyPart(messageBodyPart);<br /><br />      // Part two is attachment<br />      messageBodyPart = new MimeBodyPart();<br />      DataSource source = <br />         new FileDataSource(fileAttachment);<br />      messageBodyPart.setDataHandler(<br />         new DataHandler(source));<br />      messageBodyPart.setFileName(fileAttachment);<br />      multipart.addBodyPart(messageBodyPart);<br /><br />      // Put parts in message<br />      message.setContent(multipart);<br /><br />      // Send the message<br />      Transport.send( message );<br /><img src ="http://www.tkk7.com/ltc603/aggbug/29111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/ltc603/" target="_blank">阿成</a> 2006-01-24 15:14 <a href="http://www.tkk7.com/ltc603/archive/2006/01/24/29111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java常见问题集锦Q自Sun中方站)http://www.tkk7.com/ltc603/archive/2006/01/18/28501.html阿成阿成Wed, 18 Jan 2006 07:39:00 GMThttp://www.tkk7.com/ltc603/archive/2006/01/18/28501.htmlhttp://www.tkk7.com/ltc603/comments/28501.htmlhttp://www.tkk7.com/ltc603/archive/2006/01/18/28501.html#Feedback0http://www.tkk7.com/ltc603/comments/commentRss/28501.htmlhttp://www.tkk7.com/ltc603/services/trackbacks/28501.html若通过ObjectOutputStream向一个文件中多次以追加方式写入object,Z么用ObjectInputStreamdq些object时会产生StreamCorruptedException?  

{?  
使用~省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必M一对应.ObjectOutputStream的构造函C向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头.因此,多次以追加方式向一个文件中写入object?该文件将会包含多个标识头.所以用ObjectInputStream来deserializeq个ObjectOutputStream?生StreamCorruptedException.一U解x法是可以构造一个ObjectOutputStream的子c?q覆盖writeStreamHeader()Ҏ.被覆盖后的writeStreamHeader()Ҏ应判断是否ؓ首次向文件中写入object,?则调用super.writeStreamHeader();若否,即以q加方式写入object?则应调用ObjectOutputStream.reset()Ҏ.  

?  
对象的序列化(serialization)cL面向的,应如何将对象写入到随机存取文件中?  

{?  
目前,没有直接的方法可以将对象写入到随机存取文件中.  
但是可以使用ByteArray输入/输出作Z?来向随机存取文g中写入或从随机存取文件中d字节,q且可以利用字节来创徏对象输入/输出?以用于读写对?需要注意的是在字节中要包含一个完整的对象,否则d对象时将发生错误. 例如,java.io.ByteArrayOutputStream可用于获取ObjectOutputStream的字节流,从中可得到byte数组q可之写入到随机存取文件中.相反,我们可以从随机存取文件中d字节数组,利用它可构造ByteArrayInputStream,q而构造出ObjectInputStream,以读取对?  

?  
q行RMI应用?可不可以不手工启动名字服务rmiregistry,而是从程序中启动?  

{?  
可以. java.rmi包中提供了类java.rmi.registry.LocateRegistry,用于获取名字服务或创建名字服?调用LocateRegistry.createRegistry(int port)Ҏ可以在某一特定端口创徏名字服务,从而用h需再手工启动rmiregistry.此外,LocateRegistry.getRegistry(String host,int port)Ҏ可用于获取名字服?  

?  
使用cPrintJobq行打印操作?应如何设|打印机名等打印属?  

{?  
使用如下Ҏ可以获得PrintJob的实例用于控制打印操?  


Toolkit.getPrintJob(Frame f, String jobtitle, Properties prop)  

那么对于打印属性的讄可以通过对prop的属性设|来实现,打印属性包?  

awt.print.destination: 可以?printer"?file"  

awt.print.printer: 打印机名  

awt.print.fileName: 打印文g名 ?br />
awt.print.numCopies: 打印份数  

awt.print.options: 打印命o的打印选项  

awt.print.orientation: 打印方向,可以?portrait"?landscape"  

awt.print.paperSize: U张大小,可以?letter","legal","executive"?a4"  






?  
在JDK1.1中Threadcd义了suspend()和resume()Ҏ,但是在JDK1.2中已l过?应用什么方法来替代?  

{?  
Thread.suspend本n易于产生死锁.如果一个目标线E对某一关键pȝ资源q行了加锁操?然后该线E被suspend,那么除非该线E被resume,否则其它U程都将无法讉K该系l资?如果另外一个线E将调用resume,使该U程l箋q行,而在此之?它也需要访问这一pȝ资源,则将产生死锁.  

因此,在Java 2?比较行的方式是定义U程的状态变?q目标U程轮询该状态变?当状态ؓ悬挂状态时,可以使用wait()Ҏ使之处于{待状?一旦需要该U程l箋q行,其它U程会调用notify()Ҏ来通知?  

?  
使用JDBC~程,应如何控制结果集ResultSet的指?使之能够上下Ud,以及Ud到结果集的第一行和最后一?  

{?  
在JDK1.1?ResultSetcM只定义了next()Ҏ支持数据指针的下U?但在Java 2?ResultSetcd加了如下Ҏ支持数据指针的移?包括:  


ResultSet.first():数据指针移到结果集的第一行 ?br />
ResultSet.last(): 数据指针移到结果集的最后一行 ?br />
ResultSet.previous(): 数据指针上UM行 ?br />

以上的方法定义在JDBC2.0的规范中,所有支持JDBC 2.0的JDBC驱动E序都可以支持上q方?目前Intersolv和OpenLink{JDBC驱动E序厂商均有产品支持JDBC 2.0 .  


?  
哪几UWeb Server支持Servlet?如何使IIS支持Servlet?  

{?  
目前,支持Servlet的服务器端品主要有: Sun公司的Java WebServer,Lotus DominoGo WebServer,BEA weblogic Tengah Server,Jigsaw,NetForge,AcmeServer和Mot Bays Jetty{?  

此外,一些第三方厂商也开发了Servlet engine,以其它WebServer(如Netscape Web Server,IIS{?能够q行Servlet,如LiveSoftware的Jrun(http://www.livesoftware.com/ products/jrun/){?  

?  
如何在Java应用中将囑փ存储到图像文件中?  

{?  
Java Advanced Imaging API(包含在Java Media API?允许在Java应用中执行复杂的,高性能的图像处?JAI API提供了存储图像的能力.目前,JAI API支持以下几种囑փ文g格式:BMP,JEPG,PNG,PNM,TIFF.下面l出了将囑փ存储到BMP文g的一D代?  


OutputStream os = new FileOutputStream(fileToWriteTo);  

BMPEncodeParam param = new BMPEncodeParam();  

ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os, param);  

enc.encode(img);  

os.close();  

有关存储囑փ文g的编E指南请参考以下网?  

http://java.sun.com/products/java-media/jai/forDevelopers/jai-guide/  




?  
如何用Java语言向串口读写数? font>  

{?  
Sun公司的Java Communication API2.0可用于读写串?它支持RS232串口和IEEE 1284 q口,提供了一U与q_无关的串/q口通信机制.

阿成 2006-01-18 15:39 发表评论
]]>
վ֩ģ壺 ۺѾƷþþ| ɫþþ99Ʒ91| Ʒһѹۿ | Ļ| vaþþþͬ | ˾Ʒձַ| þþþþþۺձ| avպavŷv| ŮëƬѹۿ97| 100018Ƶ| sihuƷ| ҹƬ69| avպר߹ۿ| ޾Ʒһ| һ234վ| Ƶ߹ۿ| ޾ƷAAAƬ| ѳ¼Ƶ| Ʒҹѹۿ| ëƬƵѹۿ| av벻߹ۿ| 91þԭ| þþþùƷѿ| Ůcaoվѿ߿| 99re6ƵƷ| һƵ| 鵺̳Ƶ| 鶹ȫַ| һAëƬѹۿþþƷ| ٶ˽ȫֱ| ƯŮ| ҹҹˬ| վ߲Ƶѹۿ| ʮ˽Ļվ| igaoƵ| ȫƵ߹ۿ| òѸƵ| **ʵһëƬaa| ҳվѹۿ| ѿٸƵ| ۺϽ޺ݺ|