﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-cyantide-随笔分类-java</title><link>http://www.blogjava.net/cyantide/category/36404.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 19 Mar 2010 18:21:40 GMT</lastBuildDate><pubDate>Fri, 19 Mar 2010 18:21:40 GMT</pubDate><ttl>60</ttl><item><title>java vm xms xmx查看</title><link>http://www.blogjava.net/cyantide/archive/2010/03/19/315982.html</link><dc:creator>cyantide</dc:creator><author>cyantide</author><pubDate>Fri, 19 Mar 2010 15:24:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2010/03/19/315982.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/315982.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2010/03/19/315982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/315982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/315982.html</trackback:ping><description><![CDATA[&lt;%@ page language="java" contentType="text/html; charset=UTF-8"%&gt;<br />
&lt;html&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&lt;%= "TotalMemory :::: " + (Runtime.getRuntime().totalMemory()/(1024*1024) + "M") %&gt;&nbsp; <br />
&nbsp;&nbsp; &lt;%="Max Memory :::: " + (Runtime.getRuntime().maxMemory()/(1024*1024) + "M")%&gt;&nbsp; <br />
&nbsp;&nbsp; &lt;%="Free Memory :::: " + (Runtime.getRuntime().freeMemory()/(1024*1024) + "M")%&gt;&nbsp;&nbsp;&nbsp; <br />
&lt;/html&gt;<br />
<br />
<br />
<br />
cmd<br />
&nbsp;&nbsp; java -Xmx1024M -Xms1024M -version
<img src ="http://www.blogjava.net/cyantide/aggbug/315982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">cyantide</a> 2010-03-19 23:24 <a href="http://www.blogjava.net/cyantide/archive/2010/03/19/315982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java面试题</title><link>http://www.blogjava.net/cyantide/archive/2009/01/13/251063.html</link><dc:creator>cyantide</dc:creator><author>cyantide</author><pubDate>Tue, 13 Jan 2009 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2009/01/13/251063.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/251063.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2009/01/13/251063.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/251063.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/251063.html</trackback:ping><description><![CDATA[<p><font style="background-color: #cce8cf">第一，谈谈final, finally, finalize的区别。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　final 用于声明属性，方法和类，分别表示属性不可变，方法不可覆盖，类不可继承。finally是异常处理语句结构的一部分，表示总是执行。finalize是 Object类的一个方法，在垃圾收集器执行的时候会调用被回收对象的此方法，可以覆盖此方法提供垃圾收集时的其他资源回收，例如关闭文件等。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　可以继承其他类或完成其他接口，在swing编程中常用此方式。　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第三，Static Nested Class 和 Inner Class的不同，说得越多越好(面试题有的很笼统)。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　Static Nested Class是被声明为静态（static）的内部类，它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第四，&amp;和&amp;&amp;的区别。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　&amp;是位运算符，表示按位与运算，&amp;&amp;是逻辑运算符，表示逻辑与（and）.　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第五，HashMap和Hashtable的区别。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　HashMap是Hashtable的轻量级实现（非线程安全的实现），他们都完成了Map接口，主要区别在于HashMap允许空（null）键值（key）,由于非线程安全，效率上可能高于Hashtable.　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第六，Collection 和 Collections的区别。 </font></p>
<p><font style="background-color: #cce8cf">　　 </font></p>
<p><font style="background-color: #cce8cf">　Collection是集合类的上级接口，继承与他的接口主要有Set 和List.Collections是针对集合类的一个帮助类，他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第七，什么时候用assert。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　1.4新增关键字（语法），用于测试boolean表达式状态，可用于调试程序。使用方法 assert ，表示如果表达式为真（true）,则下面的语句执行，否则抛出AssertionError。另外的使用方式assert &lt; boolean表达式&gt;:，表示如果表达式为真，后面的表达式忽略，否则后面表达式的值用于AssertionError的构建参数。注意编译时要增加-source 1.4 参数，否则报错。]运行时要增加 &#8211;ea参数，否则assert行被忽略　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第八，GC是什么? 为什么要有GC? </font></p>
<p><font style="background-color: #cce8cf">　　 </font></p>
<p><font style="background-color: #cce8cf">　GC是垃圾收集的意思（Gabage Collection）,内存处理是编程人员容易出现问题的地方，忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃，Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的，Java语言没有提供释放已分配内存的显示操作方法。 　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第九，String s = new String("xyz");创建了几个String Object? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　两个　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十，Math.round(11.5)等於多少? Math.round(-11.5)等於多少? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　Math.round(11.5)==12Math.round(-11.5)==-11round方法返回与参数最接近的长整数，参数加1/2后求其floor.　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十一，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　short s1 = 1; s1 = s1 + 1; （s1+1运算结果是int型，需要强制转换类型）short s1 = 1; s1 += 1;（可以正确编译）　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十二，sleep() 和 wait() 有什么区别? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　sleep是线程类（Thread）的方法，导致此线程暂停执行指定时间，给执行机会给其他线程，但是监控状态依然保持，到时后会自动恢复。调用 sleep不会释放对象锁。wait是Object类的方法，对此对象调用wait方法导致本线程放弃对象锁，进入等待此对象的等待锁定池，只有针对此对象发出notify方法（或notifyAll）后本线程才进入对象锁定池准备获得对象锁进入运行状态。　　 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十三，Java有没有goto? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　没有　　很十三的问题，如果哪个面试的问到这个问题，我劝你还是别进这家公司。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十四，数组有没有length()这个方法? String有没有length()这个方法？ </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　数组没有length()这个方法，有length的属性。 </font></p>
<p><font style="background-color: #cce8cf">　String有有length()这个方法。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十五，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现， 重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写 (Overriding)。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被&#8220;屏蔽&#8221;了。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数类型，则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 </font></p>
<p><font style="background-color: #cce8cf">第十六，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　Set里的元素是不能重复的，那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。 </font></p>
<p><font style="background-color: #cce8cf">equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖，为的是当两个分离的对象的内容和类型相配的话，返回真值。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十七，给我一个你最常见到的runtime exception。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">参考如下： </font></p>
<p><font style="background-color: #cce8cf">ArithmeticException, </font></p>
<p><font style="background-color: #cce8cf">ArrayStoreException, </font></p>
<p><font style="background-color: #cce8cf">BufferOverflowException, </font></p>
<p><font style="background-color: #cce8cf">BufferUnderflowException, </font></p>
<p><font style="background-color: #cce8cf">CannotRedoException, </font></p>
<p><font style="background-color: #cce8cf">CannotUndoException, </font></p>
<p><font style="background-color: #cce8cf">ClassCastException, </font></p>
<p><font style="background-color: #cce8cf">CMMException, </font></p>
<p><font style="background-color: #cce8cf">ConcurrentModificationException, </font></p>
<p><font style="background-color: #cce8cf">DOMException, </font></p>
<p><font style="background-color: #cce8cf">EmptyStackException, </font></p>
<p><font style="background-color: #cce8cf">IllegalArgumentException, </font></p>
<p><font style="background-color: #cce8cf">IllegalMonitorStateException, </font></p>
<p><font style="background-color: #cce8cf">IllegalPathStateException, </font></p>
<p><font style="background-color: #cce8cf">IllegalStateException, </font></p>
<p><font style="background-color: #cce8cf">ImagingOpException, </font></p>
<p><font style="background-color: #cce8cf">IndexOutOfBoundsException, </font></p>
<p><font style="background-color: #cce8cf">MissingResourceException, </font></p>
<p><font style="background-color: #cce8cf">NegativeArraySizeException, </font></p>
<p><font style="background-color: #cce8cf">NoSuchElementException, </font></p>
<p><font style="background-color: #cce8cf">NullPointerException, </font></p>
<p><font style="background-color: #cce8cf">ProfileDataException, </font></p>
<p><font style="background-color: #cce8cf">ProviderException, </font></p>
<p><font style="background-color: #cce8cf">RasterFormatException, </font></p>
<p><font style="background-color: #cce8cf">SecurityException, </font></p>
<p><font style="background-color: #cce8cf">SystemException, </font></p>
<p><font style="background-color: #cce8cf">UndeclaredThrowableException, </font></p>
<p><font style="background-color: #cce8cf">UnmodifiableSetException, </font></p>
<p><font style="background-color: #cce8cf">UnsupportedOperationException </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十八，error和exception有什么区别? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 </font></p>
<p><font style="background-color: #cce8cf">　exception 表示一种设计或实现问题。也就是说，它表示如果程序运行正常，从不会发生的情况。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第十九，List, Set, Map是否继承自Collection接口? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">List，Set是 </font></p>
<p><font style="background-color: #cce8cf">Map不是 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十，abstract class和interface有什么区别? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　声明方法的存在而不去实现它的类被叫做抽象类（abstract class），它用于要创建一个体现某些基本行为的类，并为该类声明方法，但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量，其类型是一个抽象类，并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现，否则它们也是抽象类为。取而代之，在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　接口（interface）是抽象类的变体。在接口中，所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的，没有一个 有程序体。接口只可以定义static final成员变量。接口的实现与子类相似，除了该实现类不能从接口定义中继承行为。当类实现特殊接口时，它定义（即将程序体给予）所有这种接口的方法。然后，它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类，它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换，instanceof 运算符可以用来决定某对象的类是否实现了接口。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十一，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">都不能 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十二，接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　接口可以继承接口。抽象类可以实现(implements)接口，抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十三，启动一个线程是用run()还是start()? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　启动一个线程是调用start()方法，使线程所代表的虚拟处理机处于可运行状态，这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十四，构造器Constructor是否可被override? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　构造器Constructor不能被继承，因此不能重写Overriding，但可以被重载Overloading。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十五，是否可以继承String类? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　String类是final类故不可以继承。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十六，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　不能，一个对象的一个synchronized方法只能由一个线程访问。 </font></p>
<p><font style="background-color: #cce8cf">第二十七，try {}里有一个return语句，那么紧跟在这个try后的finally {}里的code会不会被执行，什么时候被执行，在return前还是后? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">会执行，在return前执行。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十八，编程题: 用最有效率的方法算出2乘以8等於几? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">有C背景的程序员特别喜欢问这种问题。 </font></p>
<p><font style="background-color: #cce8cf">2 &lt; &lt; 3 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二十九，两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">不对，有相同的hash code。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时，参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变，但对象的引用是永远不会改变的。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第三十一，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上? </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　switch（expr1）中，expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第三十二，编程题: 写一个Singleton出来。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">&nbsp;&nbsp;&nbsp; Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。 </font></p>
<p><font style="background-color: #cce8cf">一般Singleton模式通常有几种种形式: </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">　第一种形式: 定义一个类，它的构造函数为private的，它有一个static的private的该类变量，在类初始化时实例话，通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">public class Singleton { </font></p>
<p><font style="background-color: #cce8cf">　　private Singleton(){} </font></p>
<p><font style="background-color: #cce8cf">　　//在自己内部定义自己一个实例，是不是很奇怪？ </font></p>
<p><font style="background-color: #cce8cf">　　//注意这是private 只供内部调用 </font></p>
<p><font style="background-color: #cce8cf">　　private static Singleton instance = new Singleton(); </font></p>
<p><font style="background-color: #cce8cf">　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　 </font></p>
<p><font style="background-color: #cce8cf">　　public static Singleton getInstance() { </font></p>
<p><font style="background-color: #cce8cf">　　　　return instance; 　　 </font></p>
<p><font style="background-color: #cce8cf">　　 } </font></p>
<p><font style="background-color: #cce8cf">}&nbsp; </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">第二种形式: </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">public class Singleton { </font></p>
<p><font style="background-color: #cce8cf">　　private static Singleton instance = null; </font></p>
<p><font style="background-color: #cce8cf">　　public static synchronized Singleton getInstance() { </font></p>
<p><font style="background-color: #cce8cf">　　//这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　 　 </font></p>
<p><font style="background-color: #cce8cf">　　//使用时生成实例，提高了效率！ </font></p>
<p><font style="background-color: #cce8cf">　　if (instance==null) </font></p>
<p><font style="background-color: #cce8cf">　　　　instance＝new Singleton(); </font></p>
<p><font style="background-color: #cce8cf">return instance; 　　} </font></p>
<p><font style="background-color: #cce8cf">}&nbsp; </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf">其他形式: </font></p>
<p><font style="background-color: #cce8cf">定义一个类，它的构造函数为private的，所有方法为static的。 </font></p>
<p><font style="background-color: #cce8cf">一般认为第一种形式要更加安全些 </font></p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<p><font style="background-color: #cce8cf"></font>&nbsp;</p>
<font style="background-color: #cce8cf">
<p><br />
其中也存在一些问题，下面补充一下．希望大家继续补充 </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>　 </p>
<p>1.最好介绍一下final修饰变量的情形（分开说明基本类型变量和引用类型变量）。 </p>
<p>2.不知道如何描述比较好，匿名内部类本身是一个实现了特定接口或继承了其他类的类。 </p>
<p>3.非静态类不能有static的方法。参考一下java collections framework的代码，还能说出很多东西来。 </p>
<p>4.&amp;既是位运算符，也是逻辑操作符。 </p>
<p>&amp;和&amp;&amp;都是逻辑运算符，它们的区别是，&amp;&amp;进行短路计算。 </p>
<p>6.可以补充一下，参考文档。 </p>
<p>11.说一下具体的原因可能更好。 </p>
<p>13.java有goto这个keyword，不过还没有使用。 </p>
<p>15.overload和多态没有任何关系。多态是面向对象的基本特征，是和继承、overriding相关的。原来以为把overload当作多态的一种是从C++来的，后来翻了基本c++的经典的书,也强调多态只是和继承,虚函数,overriding相关,所以不知道这个错误思想从哪来的了. </p>
<p>16.public interface Set &lt;E&gt;extends Collection &lt;E&gt;一个不包含重复元素的 collection。更确切地讲，set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2，并且最多包含一个 null 元素。正如其名称所暗示的，此接口模仿了数学上的 set 抽象。 </p>
<p>看文档就是了. </p>
<p>22."抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。"什么意思?谁规定的? </p>
<p>27.这个比较复杂,例如 </p>
<p>&nbsp;</p>
<p>public class Main { </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; public static void main(String[] args) { </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(test()); </p>
<p>&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; public static boolean test() { </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean b = false; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try { </p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return b = 4 &gt; 3; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally { </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(b); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //return false; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;&nbsp;&nbsp; }&nbsp; </p>
<p>} </p>
<p>这个例子中可以看出,return后面的表达式已经计算了,感觉return语句这里被挂起了,如果finally中没有return,这个return就返回. </p>
<p>如果finally也有return,那么就是finally中的return返回了. </p>
<p>29.碰上不守规矩的程序员谁也没办法. </p>
<p>&nbsp;</p>
<p>31.还有枚举呢 </p>
<p>32.注释有问题.</font></p>
<img src ="http://www.blogjava.net/cyantide/aggbug/251063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">cyantide</a> 2009-01-13 09:41 <a href="http://www.blogjava.net/cyantide/archive/2009/01/13/251063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java GUI 的默认显示格式设置</title><link>http://www.blogjava.net/cyantide/archive/2008/08/28/225350.html</link><dc:creator>cyantide</dc:creator><author>cyantide</author><pubDate>Thu, 28 Aug 2008 09:14:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2008/08/28/225350.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/225350.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2008/08/28/225350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/225350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/225350.html</trackback:ping><description><![CDATA[<p>Java GUI 的默认显示格式设置<br />
<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_3_90_Open_Image" onclick="this.style.display='none'; Codehighlighter1_3_90_Open_Text.style.display='none'; Codehighlighter1_3_90_Closed_Image.style.display='inline'; Codehighlighter1_3_90_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_3_90_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_3_90_Closed_Text.style.display='none'; Codehighlighter1_3_90_Open_Image.style.display='inline'; Codehighlighter1_3_90_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /><span style="color: #0000ff">try</span><span id="Codehighlighter1_3_90_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_3_90_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UIManager.setLookAndFeel(</span><span style="color: #000000">"</span><span style="color: #000000">com.sun.java.swing.plaf.windows.WindowsLookAndFeel</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img id="Codehighlighter1_109_137_Open_Image" onclick="this.style.display='none'; Codehighlighter1_109_137_Open_Text.style.display='none'; Codehighlighter1_109_137_Closed_Image.style.display='inline'; Codehighlighter1_109_137_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_109_137_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_109_137_Closed_Text.style.display='none'; Codehighlighter1_109_137_Open_Image.style.display='inline'; Codehighlighter1_109_137_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" />}</span></span><span style="color: #0000ff">catch</span><span style="color: #000000">(Exception&nbsp;e)</span><span id="Codehighlighter1_109_137_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_109_137_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
 <img src ="http://www.blogjava.net/cyantide/aggbug/225350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">cyantide</a> 2008-08-28 17:14 <a href="http://www.blogjava.net/cyantide/archive/2008/08/28/225350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java字符编码转换研究(转帖)</title><link>http://www.blogjava.net/cyantide/archive/2008/08/26/224420.html</link><dc:creator>cyantide</dc:creator><author>cyantide</author><pubDate>Tue, 26 Aug 2008 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2008/08/26/224420.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/224420.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2008/08/26/224420.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/224420.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/224420.html</trackback:ping><description><![CDATA[<h1 style="margin-bottom: 0pt; line-height: normal; text-align: center" align="center">java字符编码转换研究</h1>
<p class="1">1. 概述</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">本文主要包括以下几个方面：编码基本知识，java，系统软件，url，工具软件等。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">在下面的描述中，将以"中文"两个字为例，经查表可以知道其GB2312编码是"<u>d6d0 cec4</u>"，Unicode编码为"<u>4e2d 6587</u>"，UTF编码就是"<u>e4b8ad e69687</u>"。注意，这两个字没有iso8859-1编码，但可以用iso8859-1编码来"表示"。</p>
<p class="1">2. 编码基本知识</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">最早的编码是iso8859-1，和ascii编码相似。但为了方便表示各种各样的语言，逐渐出现了很多标准编码，重要的有如下几个。</p>
<p class="2">2.1. iso8859-1</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">属于单字节编码，最多能表示的字符范围是0-255，应用于英文系列。比如，字母'a'的编码为0x61=97。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">很明显，iso8859-1编码表示的字符范围很窄，无法表示中文字符。但是，由于是单字节编码，和计算机最基础的表示单位一致，所以很多时候，仍旧使用iso8859-1编码来表示。而且在很多协议上，默认使用该编码。比如，虽然"中文"两个字不存在iso8859-1编码，以gb2312编码为例，应该是"<u>d6d0 cec4</u>"两个字符，使用iso8859-1编码的时候则将它拆开为4个字节来表示："<u>d6 d0 ce c4</u>"（事实上，在进行存储的时候，也是以字节为单位处理的）。而如果是UTF编码，则是6个字节"<u>e4 b8 ad e6 96 87</u>"。很明显，这种表示方法还需要以另一种编码为基础。</p>
<p class="2">2.2. GB2312/GBK</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">这就是汉子的国标码，专门用来表示汉字，是双字节编码，而英文字母和iso8859-1一致（兼容iso8859-1编码）。其中gbk编码能够用来同时表示繁体字和简体字，而gb2312只能表示简体字，gbk是兼容gb2312编码的。</p>
<p class="2">2.3. unicode</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">这是最统一的编码，可以用来表示所有语言的字符，而且是定长双字节（也有四字节的）编码，包括英文字母在内。所以可以说它是不兼容iso8859-1编码的，也不兼容任何编码。不过，相对于iso8859-1编码来说，uniocode编码只是在前面增加了一个0字节，比如字母'a'为"<u>00 61</u>"。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">需要说明的是，定长编码便于计算机处理（注意GB2312/GBK不是定长编码），而unicode又可以用来表示所有字符，所以在很多软件内部是使用unicode编码来处理的，比如java。</p>
<p class="2">2.4. UTF</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">考虑到unicode编码不兼容iso8859-1编码，而且容易占用更多的空间：因为对于英文字母，unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码，utf编码兼容iso8859-1编码，同时也可以用来表示所有语言的字符，不过，utf编码是不定长编码，每一个字符的长度从1-6个字节不等。另外，utf编码自带简单的校验功能。一般来讲，英文字母都是用一个字节表示，而汉字使用三个字节。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">注意，虽然说utf是为了使用更少的空间而使用的，但那只是相对于unicode编码来说，如果已经知道是汉字，则使用GB2312/GBK无疑是最节省的。不过另一方面，值得说明的是，虽然utf编码对汉字使用3个字节，但即使对于汉字网页，utf编码也会比unicode编码节省，因为网页中包含了很多的英文字符。</p>
<p class="1">3. java对字符的处理</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">在java应用软件中，会有多处涉及到字符集编码，有些地方需要进行正确的设置，有些地方需要进行一定程度的处理。</p>
<p class="2">3.1. getBytes(charset)</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">这是java字符串处理的一个标准函数，其作用是将字符串所表示的字符按照charset编码，并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文"，正常情况下（即没有错误的时候）存储为"<u>4e2d 6587</u>"，如果charset为"gbk"，则被编码为"<u>d6d0 cec4</u>"，然后返回字节"<u>d6 d0 ce c4</u>"。如果charset为"utf8"则最后是"<u>e4 b8 ad e6 96 87</u>"。如果是"iso8859-1"，则由于无法编码，最后返回 "<u>3f 3f</u>"（两个问号）。</p>
<p class="2">3.2. new String(charset)</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">这是java字符串处理的另一个标准函数，和上一个函数的作用相反，将字节数组按照charset编码进行组合识别，最后转换为unicode存储。参考上述getBytes的例子，"gbk" 和"utf8"都可以得出正确的结果"<u>4e2d 6587</u>"，但iso8859-1最后变成了"<u>003f 003f</u>"（两个问号）。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">因为utf8可以用来表示/编码所有字符，所以new String( str.getBytes( "utf8" ), "utf8" ) === str，即完全可逆。</p>
<p class="2">3.3. setCharacterEncoding()</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">该函数用来设置http请求或者相应的编码。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">对于request，是指提交内容的编码，指定后可以通过getParameter()则直接获得正确的字符串，如果不指定，则默认使用iso8859-1编码，需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前，不能执行任何getParameter()。java doc上说明：This method must be called prior to reading request parameters or reading input using getReader()。而且，该指定只对POST方法有效，对GET方法无效。分析原因，应该是在执行第一个getParameter()的时候，java将会按照编码分析所有的提交内容，而后续的getParameter()不再进行分析，所以setCharacterEncoding()无效。而对于GET方法提交表单是，提交的内容在URL中，一开始就已经按照编码分析所有的提交内容，setCharacterEncoding()自然就无效。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">对于response，则是指定输出内容的编码，同时，该设置会传递给浏览器，告诉浏览器输出内容所采用的编码。</p>
<p class="2">3.4. 处理过程</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">下面分析两个有代表性的例子，说明java对编码有关问题的处理方法。</p>
<p class="3">3.4.1. 表单输入</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">User input<u>&nbsp; *(gbk:d6d0 cec4)&nbsp; </u>browser<u>&nbsp; *(gbk:d6d0 cec4)&nbsp; </u>web server<u>&nbsp; iso8859-1(00d6 00d 000ce 00c4)&nbsp; </u>class，需要在class中进行处理：getbytes("iso8859-1")为<u>d6 d0 ce c4</u>，new String("gbk")为<u>d6d0 cec4</u>，内存中以unicode编码则为<u>4e2d 6587</u>。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> 用户输入的编码方式和页面指定的编码有关，也和用户的操作系统有关，所以是不确定的，上例以gbk为例。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> 从browser到web server，可以在表单中指定提交内容时使用的字符集，否则会使用页面指定的编码。而如果在url中直接用?的方式输入参数，则其编码往往是操作系统本身的编码，因为这时和页面无关。上述仍旧以gbk编码为例。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> Web server接收到的是字节流，默认时（getParameter）会以iso8859-1编码处理之，结果是不正确的，所以需要进行处理。但如果预先设置了编码（通过request. setCharacterEncoding ()），则能够直接获取到正确的结果。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> 在页面中指定编码是个好习惯，否则可能失去控制，无法指定正确的编码。</p>
<p class="3">3.4.2. 文件编译</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">假设文件是gbk编码保存的，而编译有两种编码选择：gbk或者iso8859-1，前者是中文windows的默认编码，后者是linux的默认编码，当然也可以在编译时指定编码。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">Jsp<u>&nbsp; *(gbk:d6d0 cec4)&nbsp; </u>java file<u>&nbsp; *(gbk:d6d0 cec4)&nbsp; </u>compiler read<u>&nbsp; uincode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)&nbsp; </u>compiler write<u>&nbsp; utf(gbk: e4b8ad e69687; iso8859-1: *)&nbsp; </u>compiled file<u>&nbsp; unicode(gbk: 4e2d 6587; iso8859-1: 00d6 00d 000ce 00c4)&nbsp; </u>class。所以用gbk编码保存，而用iso8859-1编译的结果是不正确的。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">class<u>&nbsp; unicode(4e2d 6587)&nbsp; </u>system.out / jsp.out<u>&nbsp; gbk(d6d0 cec4)&nbsp; </u>os console / browser。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> 文件可以以多种编码方式保存，中文windows下，默认为ansi/gbk。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> 编译器读取文件时，需要得到文件的编码，如果未指定，则使用系统默认编码。一般class文件，是以系统默认编码保存的，所以编译不会出问题，但对于jsp文件，如果在中文windows下编辑保存，而部署在英文linux下运行/编译，则会出现问题。所以需要在jsp文件中用pageEncoding指定编码。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> Java编译的时候会转换成统一的unicode编码处理，最后保存的时候再转换为utf编码。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> 当系统输出字符的时候，会按指定编码输出，对于中文windows下，System.out将使用gbk编码，而对于response（浏览器），则使用jsp文件头指定的contentType，或者可以直接为response指定编码。同时，会告诉browser网页的编码。如果未指定，则会使用iso8859-1编码。对于中文，应该为browser指定输出字符串的编码。</p>
<p class="MsoBodyTextIndent" style="margin-left: 43pt; text-indent: -21pt; tab-stops: list 43.0pt"><span lang="EN-US" style="font-size: 11pt; font-family: Wingdings">l</span> browser显示网页的时候，首先使用response中指定的编码（jsp文件头指定的contentType最终也反映在response上），如果未指定，则会使用网页中meta项指定中的contentType。</p>
<p class="2">3.5. 几处设置</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">对于web应用程序，和编码有关的设置或者函数如下。</p>
<p class="3">3.5.1. jsp编译</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">指定文件的存储编码，很明显，该设置应该置于文件的开头。例如：&lt;%@page pageEncoding="GBK"%&gt;。另外，对于一般class文件，可以在编译的时候指定编码。</p>
<p class="3">3.5.2. jsp输出</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">指定文件输出到browser是使用的编码，该设置也应该置于文件的开头。例如：&lt;%@ page contentType="text/html; charset= GBK" %&gt;。该设置和response.setCharacterEncoding("GBK")等效。</p>
<p class="3">3.5.3. meta设置</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">指定网页使用的编码，该设置对静态网页尤其有作用。因为静态网页无法采用jsp的设置，而且也无法执行response.setCharacterEncoding()。例如：&lt;<ST1:PLACE w:st="on">META http-equiv="Content-Type" content="text/html; charset=GBK" /&gt;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">如果同时采用了jsp输出和meta设置两种编码指定方式，则jsp指定的优先。因为jsp指定的直接体现在response中。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">需要注意的是，apache有一个设置可以给无编码指定的网页指定编码，该指定等同于jsp的编码指定方式，所以会覆盖静态网页中的meta指定。所以有人建议关闭该设置。</p>
<p class="3">3.5.4. form设置</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">当浏览器提交表单的时候，可以指定相应的编码。例如：&lt;form accept-charset= "gb2312"&gt;。一般不必不使用该设置，浏览器会直接使用网页的编码。</p>
<p class="1">4. 系统软件</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">下面讨论几个相关的系统软件。</p>
<p class="2">4.1. mysql数据库</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">很明显，要支持多语言，应该将数据库的编码设置成utf或者unicode，而utf更适合与存储。但是，如果中文数据中包含的英文字母很少，其实unicode更为适合。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">数据库的编码可以通过mysql的配置文件设置，例如default-character-set=utf8。还可以在数据库链接URL中设置，例如： useUnicode=true&amp;characterEncoding=UTF-8。注意这两者应该保持一致，在新的sql版本里，在数据库链接URL里可以不进行设置，但也不能是错误的设置。</p>
<p class="2">4.2. apache</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">appache和编码有关的配置在httpd.conf中，例如AddDefaultCharset UTF-8。如前所述，该功能会将所有静态页面的编码设置为UTF-8，最好关闭该功能。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">另外，apache还有单独的模块来处理网页响应头，其中也可能对编码进行设置。</p>
<p class="2">4.3. linux默认编码</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">这里所说的linux默认编码，是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANG，默认编码会影响到java URLEncode的行为，下面有描述。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">建议都设置为"zh_CN.UTF-8"。</p>
<p class="2">4.4. 其它</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">为了支持中文文件名，linux在加载磁盘时应该指定字符集，例如：mount /dev/hda5 /mnt/hda5/ -t ntfs -o iocharset=gb2312。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">另外，如前所述，使用GET方法提交的信息不支持request.setCharacterEncoding()，但可以通过tomcat的配置文件指定字符集，在tomcat的server.xml文件中，形如：&lt;Connector ... URIEncoding="GBK"/&gt;。这种方法将统一设置所有请求，而不能针对具体页面进行设置，也不一定和browser使用的编码相同，所以有时候并不是所期望的。</p>
<p class="1">5. URL地址</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">URL地址中含有中文字符是很麻烦的，前面描述过使用GET方法提交表单的情况，使用GET方法时，参数就是包含在URL中。</p>
<p class="2">5.1. URL编码</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">对于URL中的一些特殊字符，浏览器会自动进行编码。这些字符除了"/?&amp;"等外，还包括unicode字符，比如汉子。这时的编码比较特殊。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">IE有一个选项"总是使用UTF-8发送URL"，当该选项有效时，IE将会对特殊字符进行UTF-8编码，同时进行URL编码。如果改选项无效，则使用默认编码"GBK"，并且不进行URL编码。但是，对于URL后面的参数，则总是不进行编码，相当于UTF-8选项无效。比如"中文.html?a=中文"，当UTF-8选项有效时，将发送链接"%<u>e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87</u>"；而UTF-8选项无效时，将发送链接"<u>\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87</u>"。注意后者前面的"中文"两个字只有4个字节，而前者却有18个字节，这主要时URL编码的原因。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">当web server（tomcat）接收到该链接时，将会进行URL解码，即去掉"%"，同时按照ISO8859-1编码（上面已经描述，可以使用URLEncoding来设置成其它编码）识别。上述例子的结果分别是"<u>\ue4\ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87</u>"和"<u>\u4e\u2d\u65\u87.html?a=\u4e\u2d\u65\u87</u>"，注意前者前面的"中文"两个字恢复成了6个字符。这里用"\u"，表示是unicode。</p>
<p class="MsoBodyTextIndent" style="text-indent: 22pt">所以，由于客户端设置的不同，相同的链接，在服务器上得到了不同结果。这个问题不少人都遇到，却没有很好的解决办法。所以有的网站会建议用户尝试关闭UTF-8选项。不过，下面会描述一个更好的处理办法。</p>
<p class="2">5.2. rewrite</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">熟悉的人都知道，apache有一个功能强大的rewrite模块，这里不描述其功能。需要说明的是该模块会自动将URL解码（去除%），即完成上述web server（tomcat）的部分功能。有相关文档介绍说可以使用[NE]参数来关闭该功能，但我试验并未成功，可能是因为版本（我使用的是apache <ST1:CHSDATE w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">2.0.54）问题。另外，当参数中含有"?&amp; "等符号的时候，该功能将导致系统得不到正常结果。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">rewrite本身似乎完全是采用字节处理的方式，而不考虑字符串的编码，所以不会带来编码问题。</p>
<p class="2">5.3. URLEncode.encode()</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">这是Java本身提供对的URL编码函数，完成的工作和上述UTF-8选项有效时浏览器所做的工作相似。值得说明的是，java已经不赞成不指定编码来使用该方法（deprecated）。应该在使用的时候增加编码指定。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">当不指定编码的时候，该方法使用系统默认编码，这会导致软件运行结果得不确定。比如对于"中文"，当系统默认编码为"gb2312"时，结果是"%<u>4e%2d%65%87</u>"，而默认编码为"UTF-8"，结果却是"%<u>e4%b8%ad%e6%96%87</u>"，后续程序将难以处理。另外，这儿说的系统默认编码是由运行tomcat时的环境变量LC_ALL和LANG等决定的，曾经出现过tomcat重启后就出现乱码的问题，最后才郁闷的发现是因为修改修改了这两个环境变量。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">建议统一指定为"UTF-8"编码，可能需要修改相应的程序。</p>
<p class="2">5.4. 一个解决方案</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">上面说起过，因为浏览器设置的不同，对于同一个链接，web server收到的是不同内容，而软件系统有无法知道这中间的区别，所以这一协议目前还存在缺陷。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">针对具体问题，不应该侥幸认为所有客户的IE设置都是UTF-8有效的，也不应该粗暴的建议用户修改IE设置，要知道，用户不可能去记住每一个web server的设置。所以，接下来的解决办法就只能是让自己的程序多一点智能：根据内容来分析编码是否UTF-8。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">比较幸运的是UTF-8编码相当有规律，所以可以通过分析传输过来的链接内容，来判断是否是正确的UTF-8字符，如果是，则以UTF-8处理之，如果不是，则使用客户默认编码（比如"GBK"），下面是一个判断是否UTF-8的例子，如果你了解相应规律，就容易理解。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">public static boolean isValidUtf8(byte[] b,int aMaxCount){</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int lLen=b.length,lCharCount=0;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;lLen &amp;&amp; lCharCount&lt;aMaxCount;++lCharCount){</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte lByte=b[i++];//to fast operation, ++ now, ready for the following for(;;)</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(lByte&gt;=0) continue;//&gt;=0 is normal ascii</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(lByte&lt;(byte)0xc0 || lByte&gt;(byte)0xfd) return false;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int lCount=lByte&gt;(byte)0xfc?5:lByte&gt;(byte)0xf8?4</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :lByte&gt;(byte)0xf0?3:lByte&gt;(byte)0xe0?2:1;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i+lCount&gt;lLen) return false;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int j=0;j&lt;lCount;++j,++i) if(b[i]&gt;=(byte)0xc0) return false;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">}</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">相应地，一个使用上述方法的例子如下：</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">public static String getUrlParam(String aStr,String aDefaultCharset)</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">throws UnsupportedEncodingException{</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(aStr==null) return null;</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] lBytes=aStr.getBytes("ISO-8859-1");</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset);</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">}</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">不过，该方法也存在缺陷，如下两方面：</p>
<p class="MsoBodyTextIndent" style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><span lang="EN-US" style="font-family: Wingdings">l</span> 没有包括对用户默认编码的识别，这可以根据请求信息的语言来判断，但不一定正确，因为我们有时候也会输入一些韩文，或者其他文字。</p>
<p class="MsoBodyTextIndent" style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><span lang="EN-US" style="font-family: Wingdings">l</span> 可能会错误判断UTF-8字符，一个例子是"学习"两个字，其GBK编码是" <u>\xd1\xa7\xcf\xb0</u>"，如果使用上述isValidUtf8方法判断，将返回true。可以考虑使用更严格的判断方法，不过估计效果不大。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">有一个例子可以证明google也遇到了上述问题，而且也采用了和上述相似的处理方法，比如，如果在地址栏中输入"<a href="http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习">http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;q=学习</a>"，google将无法正确识别，而其他汉字一般能够正常识别。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">最后，应该补充说明一下，如果不使用rewrite规则，或者通过表单提交数据，其实并不一定会遇到上述问题，因为这时可以在提交数据时指定希望的编码。另外，中文文件名确实会带来问题，应该谨慎使用。</p>
<p class="1">6. 其它</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">下面描述一些和编码有关的其他问题。</p>
<p class="2">6.1. SecureCRT</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">除了浏览器和控制台与编码有关外，一些客户端也很有关系。比如在使用SecureCRT连接linux时，应该让SecureCRT的显示编码（不同的session，可以有不同的编码设置）和linux的编码环境变量保持一致。否则看到的一些帮助信息，就可能是乱码。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">另外，mysql有自己的编码设置，也应该保持和SecureCRT的显示编码一致。否则通过SecureCRT执行sql语句的时候，可能无法处理中文字符，查询结果也会出现乱码。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">对于Utf-8文件，很多编辑器（比如记事本）会在文件开头增加三个不可见的标志字节，如果作为mysql的输入文件，则必须要去掉这三个字符。（用linux的vi保存可以去掉这三个字符）。一个有趣的现象是，在中文windows下，创建一个新txt文件，用记事本打开，输入"连通"两个字，保存，再打开，你会发现两个字没了，只留下一个小黑点。</p>
<p class="2">6.2. 过滤器</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">如果需要统一设置编码，则通过filter进行设置是个不错的选择。在filter class中，可以统一为需要的请求或者回应设置编码。参加上述setCharacterEncoding()。这个类apache已经给出了可以直接使用的例子SetCharacterEncodingFilter。</p>
<p class="2">6.3. POST和GET</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">很明显，以POST提交信息时，URL有更好的可读性，而且可以方便的使用setCharacterEncoding()来处理字符集问题。但GET方法形成的URL能够更容易表达网页的实际内容，也能够用于收藏。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">从统一的角度考虑问题，建议采用GET方法，这要求在程序中获得参数是进行特殊处理，而无法使用setCharacterEncoding()的便利，如果不考虑rewrite，就不存在IE的UTF-8问题，可以考虑通过设置URIEncoding来方便获取URL中的参数。</p>
<p class="2">6.4. 简繁体编码转换</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">GBK同时包含简体和繁体编码，也就是说同一个字，由于编码不同，在GBK编码下属于两个字。有时候，为了正确取得完整的结果，应该将繁体和简体进行统一。可以考虑将UTF、GBK中的所有繁体字，转换为相应的简体字，BIG5编码的数据，也应该转化成相应的简体字。当然，仍旧以UTF编码存储。</p>
<p class="MsoBodyTextIndent" style="text-indent: 21pt">例如，对于"语言 語言"，用UTF表示为"<u>\x</u><u>E8\xAF\xAD\xE8\xA8\x80 \xE8\xAA\x9E\xE8\xA8\x80</u>"，进行简繁体编码转换后应该是两个相同的 "<u>\x</u><u>E8\xAF\xAD\xE8\xA8\x80&gt;</u>"。</p>
<p class="MsoBodyTextIndent">&nbsp;</ST1:CHSDATE></ST1:PLACE></p>
 <img src ="http://www.blogjava.net/cyantide/aggbug/224420.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">cyantide</a> 2008-08-26 10:50 <a href="http://www.blogjava.net/cyantide/archive/2008/08/26/224420.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中的系统属性以及环境变量(转帖)</title><link>http://www.blogjava.net/cyantide/archive/2008/08/15/222228.html</link><dc:creator>cyantide</dc:creator><author>cyantide</author><pubDate>Fri, 15 Aug 2008 06:04:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2008/08/15/222228.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/222228.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2008/08/15/222228.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/222228.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/222228.html</trackback:ping><description><![CDATA[<p><a name="EnvironmentVSSystemProperties">从概念上讲，<em>系统属性</em> 和<em>环境变量</em> 都是名称与值之间的映射。两种机制都能用来将用户定义的信息传递给 Java 进程。环境变量产生更多的全局效应，因为它们不仅对Java 子进程可见，而且对于定义它们的进程的所有子进程都是可见的。在不同的操作系统上，它们的语义有细微的差别，比如，不区分大小写。因为这些原因，环境变量更可能有意料不到的副作用。最好在可能的地方使用系统属性。环境变量应该在需要全局效应的时候使用，或者在外部系统接口要求使用环境变量时使用（比如 <code>PATH</code>）。</a></p>
<p>代码如下：</p>
<p>//import java.util.*;<br />
import java.util.Properties;<br />
import java.util.Enumeration;<br />
import java.util.Map;<br />
import java.util.Set;<br />
import java.util.Iterator;</p>
<p>public class GetSysPropertiesAndEnv<br />
{<br />
&nbsp;public static void main(String [] args)<br />
&nbsp;{<br />
&nbsp;&nbsp;//获取所有系统属性<br />
&nbsp;&nbsp; Properties prpt = System.getProperties();<br />
&nbsp;&nbsp; Enumeration enm = prpt.propertyNames();&nbsp; //返回系统属性列表中所有键的枚举<br />
&nbsp;&nbsp; String key = "";<br />
&nbsp;&nbsp; System.out.println("当前系统属性如下：=========");<br />
&nbsp;&nbsp; while(enm.hasMoreElements())<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;key = (String) enm.nextElement();<br />
&nbsp;&nbsp;&nbsp;System.out.println(key+":"+System.getProperty(key,"undefined"));<br />
&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;//获取所有环境变量的设置<br />
&nbsp;&nbsp; Map map = System.getenv();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//返回系统环境变量的字符串映射视图。<br />
&nbsp;&nbsp; Set&nbsp; set&nbsp; = map.keySet();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//返回映射中包含的键的 set 视图<br />
&nbsp;&nbsp; System.out.println("当前环境变量如下：=========");<br />
&nbsp;&nbsp; Iterator itr = set.iterator();<br />
&nbsp;&nbsp; while(itr.hasNext())<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;key = (String) itr.next();<br />
&nbsp;&nbsp;&nbsp;System.out.println(key+":"+map.get(key));<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
}</p>
<p>其中个人认为比较重要的系统属性如下：<br />
<br />
java.home：Java 安装目录 (比如D:\JavaStudio\jdk15\jre)<br />
java.class.path：Java 类路径<br />
java.vm.version：Java虚拟机版本号(比如：1.5.0-b64）<br />
java.version：Java版本号(比如：1.5.0)</p>
<p>os.name：操作系统的名称(比如：Windows XP)<br />
os.version：操作系统的版本(比如：Windows XP 的版本为5.1)</p>
<p>user.home：用户的主目录 (比如：C:\Documents and Settings\zhangsan)<br />
user.name：当前用户名<br />
user.country：当前用户所属国家<br />
user.dir：用户的当前工作目录<br />
<br />
比较重要的环境变量（Windows操作系统）：<br />
<br />
%COMPUTERNAME%&nbsp;&nbsp;&nbsp;&nbsp; 返回计算机的名称。<br />
%COMSPEC%&nbsp;&nbsp;&nbsp;&nbsp; 返回命令行解释器可执行程序的准确路径。</p>
<p>%WINDIR%&nbsp;&nbsp;&nbsp; 返回操作系统目录的位置。<br />
%OS%&nbsp;&nbsp;&nbsp;&nbsp; 返回操作系统的名称。Windows 2000 将操作系统显示为 Windows_NT。<br />
%PATH%&nbsp;&nbsp;&nbsp; 指定可执行文件的搜索路径。</p>
<p>%USERDOMAIN%&nbsp;&nbsp;&nbsp; 返回包含用户帐户的域的名称。<br />
%USERNAME%&nbsp;&nbsp;&nbsp; 返回当前登录的用户的名称。</p>
<div></div> <img src ="http://www.blogjava.net/cyantide/aggbug/222228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">cyantide</a> 2008-08-15 14:04 <a href="http://www.blogjava.net/cyantide/archive/2008/08/15/222228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA的util包(转帖)</title><link>http://www.blogjava.net/cyantide/archive/2008/07/09/213528.html</link><dc:creator>cyantide</dc:creator><author>cyantide</author><pubDate>Wed, 09 Jul 2008 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/cyantide/archive/2008/07/09/213528.html</guid><wfw:comment>http://www.blogjava.net/cyantide/comments/213528.html</wfw:comment><comments>http://www.blogjava.net/cyantide/archive/2008/07/09/213528.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cyantide/comments/commentRss/213528.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cyantide/services/trackbacks/213528.html</trackback:ping><description><![CDATA[<p><strong><em>Java<sup><font size="-2">TM</font></sup> 2 Platform<br />
Standard Ed. 5.0</em></strong></p>
<br />
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#3366ff"> </font><font color="#800080">在JAVA的util包中有两个所有</font><font color="#800080">集合的父接口</font><font color="#800080">Collection和Map,它们的父子关系：</font></p>
<br />
<p><font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +Collection 这个接口extends自 --java.lang.Iterable接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +List 接口 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -ArrayList 类<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -LinkedList 类<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -Vector 类&nbsp;&nbsp;&nbsp;&nbsp; 此类是实现同步的</font></p>
<br />
<p><font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +Queue 接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +不常用，在此不表.</font></p>
<br />
<p><font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +Set 接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +SortedSet 接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -TreeSet 类<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -HashSet</font></p>
<br />
<p><font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +Map 接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -HashMap 类 (除了不同步和允许使用 null 键/值之外,与 Hashtable 大致相同.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -Hashtable 类 此类是实现同步的,不允许使用 null 键值<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +SortedMap 接口<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -TreeMap 类</font></p>
<br />
<p><font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下对众多接口和类的简单说明：首先不能不先说一下数组（Array）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#0000ff"><strong>一、Array ， Arrays</strong></font></p>
<br />
<p><font size="2">Java所有&#8220;存储及随机访问一连串对象&#8221;的做法，array是最有效率的一种。</font></p>
<br />
<p><font size="2">1、<br />
效率高，但容量固定且无法动态改变。<br />
array还有一个缺点是，无法判断其中实际存有多少元素，length只是告诉我们array的容量。</font></p>
<br />
<p><font size="2">2、Java中有一个Arrays类，专门用来操作array。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arrays中拥有一组static函数，<br />
equals()：比较两个array是否相等。array拥有相同元素个数，且所有对应元素两两相等。<br />
fill()：将值填入array中。<br />
sort()：用来对array进行排序。<br />
binarySearch()：在排好序的array中寻找元素。<br />
System.arraycopy()：array的复制。</font></p>
<br />
<p><br />
<strong><font color="#0000ff">二、Collection ， Map</font></strong></p>
<br />
<p><font size="2">若撰写程序时不知道究竟需要多少对象，需要在空间不足时自动扩增容量，则需要使用容器类库，array不适用。</font></p>
<br />
<p><font size="2"><strong>1、Collection 和 Map 的区别</strong></font></p>
<br />
<p><font size="2">容器内每个为之所存储的元素个数不同。<br />
Collection类型者，每个位置只有一个元素。<br />
Map类型者，持有 key-value pair，像个小型数据库。</font></p>
<br />
<p><font size="2"><strong>2、Java2容器类类库的用途是&#8220;保存对象&#8221;，它分为两类，各自旗下的子类关系</strong></font></p>
<br />
<p><font size="2"><strong><font color="#3366ff">Collection<br />
</font></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --<font color="#3366ff">List</font>：将以特定次序存储元素。所以取出来的顺序可能和放入顺序不同。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --<font color="#ff6600">ArrayList / LinkedList / Vector<br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --<font color="#3366ff">Set</font> ： 不能含有重复的元素<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --<font color="#ff6600">HashSet /TreeSet</font><br />
<strong><font color="#3366ff">Map</font></strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --<font color="#ff6600">HashMap<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#000000">--</font>HashTable<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#000000">--</font>TreeMap</font></font></p>
<br />
<p>　Map----一组成对的&#8220;键值对&#8221;对象，即其元素是成对的对象，最典型的应用就是数据字典，并且还有其它广泛的应用。另外，Map可以返回其所 <br />
有键组成的Set和其所有值组成的Collection，或其键值对组成的Set，并且还可以像数组一样扩展多维Map，只要让Map中键值对的每个&#8220;值 <br />
&#8221;是一个Map即可。<br />
<br />
　<strong><font color="#3366ff" size="2">Collection下 </font></strong><font color="#0000ff">1.迭代器<br />
</font><br />
　　迭代器是一种设计模式，它是一个对象，它可以遍历并选择序列中的对象，而开发人员不需要了解该序列的底层结构。迭代器通常被称为&#8220;轻量级&#8221;对象，因为创建它的代价小。<br />
<br />
　　Java中的Iterator功能比较简单，并且只能单向移动：<br />
<br />
　　(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时，它返回序列的第一个元素。<font color="#0000ff">注意：</font><font color="#0000ff">iterator()方法是java.lang.Iterable接口,被<font color="#0000ff" size="2">Collection继承。</font><br />
</font><br />
<br />
　　(2) 使用next()获得序列中的下一个元素。<br />
<br />
　　(3) 使用hasNext()检查序列中是否还有元素。<br />
<br />
　　(4) 使用remove()将迭代器新返回的元素删除。<br />
<br />
　　Iterator是Java迭代器最简单的实现，为List设计的ListIterator具有更多的功能，它可以从两个方向遍历List，也可以从List中插入和删除元素。<br />
<br />
　　<font color="#0000ff">2.List的功能方法<br />
</font><br />
　 <br />
　List(interface): <br />
次序是List最重要的特点；它确保维护元素特定的顺序。List为Collection添加了许多方法，使得能够向List中间插入与移除元素(只推荐 <br />
LinkedList使用)。一个List可以生成ListIterator，使用它可以从两个方向遍历List，也可以从List中间插入和删除元素。<br />
<br />
　　ArrayList: 由数组实现的List。它允许对元素进行快速随机访问，但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList，而不是用来插入和删除元素，因为这比LinkedList开销要大很多。<br />
<br />
　 <br />
　LinkedList: <br />
由列表实现的List。对顺序访问进行了优化，向List中间插入与删除得开销不大，随机访问则相对较慢(可用ArrayList代替)。它具有方法 <br />
addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()，这些方 <br />
法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。<br />
<br />
　　<font color="#0000ff">3.Set的功能方法<br />
</font><br />
　 <br />
　Set(interface): <br />
存入Set的每个元素必须是唯一的，这也是与List不同的，因为Set不保存重复元素。加入Set的Object必须定义equals()方法以确保对 <br />
象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。<br />
<br />
　　HashSet: HashSet能快速定位一个元素，存入HashSet的对象必须定义hashCode()。<br />
<br />
　　TreeSet: 保持次序的Set，底层为树结构。使用它可以从Set中提取有序的序列。<br />
<br />
　　LinkedHashSet: 具有HashSet的查询速度，且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时，结果会按元素插入的次序显示。<br />
<br />
　 <br />
　HashSet采用散列函数对元素进行排序，这是专门为快速查询而设计的；TreeSet采用红黑树的数据结构进行排序元 <br />
素；LinkedHashSet内部使用散列以加快查询速度，同时使用链表维护元素的次序，使得看起来元素是以插入的顺序保存的。需要注意的是，生成自己 <br />
的类时，Set需要维护元素的存储顺序，因此要实现Comparable接口并定义compareTo()方法。</p>
<br />
<p><font size="2"><strong>3、其他特征</strong></font></p>
<br />
<p><font size="2">*&nbsp;&nbsp;&nbsp;&nbsp; List，Set，Map将持有对象一律视为Object型别。<br />
*&nbsp;&nbsp;&nbsp;&nbsp; Collection、List、Set、Map都是接口，不能实例化。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class，这些才可被实例化。<br />
*&nbsp;&nbsp;&nbsp;&nbsp; vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。</font></p>
<br />
<p><br />
<strong>三、Collections</strong></p>
<br />
<p><font size="2"><strong><font color="#3366ff">Collections是针对集合类的一个帮助类。</font></strong>提供了一系列<font color="#ff6600">静态</font>方法实现对各种集合的搜索、排序、线程完全化等操作。<br />
相当于对Array进行类似操作的类——Arrays。<br />
如，Collections.max(Collection coll); 取coll中最大的元素。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Collections.sort(List list); 对list中元素排序<br />
</font></p>
<br />
<p><strong>四、如何选择？</strong></p>
<br />
<p><font size="2"><strong>1、容器类和Array的区别、择取</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 容器类仅能持有对象引用（指向对象的指针），而不是将对象信息copy一份至数列某位置。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 一旦将对象置入容器内，便损失了该对象的型别信息。</font></p>
<br />
<p><font size="2"><strong>2、</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 在各种Lists中，最好的做法是以ArrayList作为缺省选择。当插入、删除频繁时，使用LinkedList()；<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Vector总是比ArrayList慢，所以要尽量避免使用。<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 在各种Sets中，HashSet通常优于HashTree（插入、查找）。只有当需要产生一个经过排序的序列，才用TreeSet。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HashTree存在的唯一理由：能够维护其内元素的排序状态。<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 在各种Maps中<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HashMap用于快速查找。<br />
&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp; 当元素个数固定，用Array，因为Array效率是最高的。</font></p>
<br />
<p><font color="#3366ff" size="2"><strong>结论：最常用的是ArrayList，HashSet，HashMap，Array。而且，我们也会发现一个规律，用TreeXXX都是排序的。</strong></font></p>
<br />
<p><font size="2"><br />
<strong><font color="#ff6600">注意：</font></strong></font></p>
<br />
<p>1、<font color="#3366ff">Collection没有get()方法</font>来取得某个元素。只能通过iterator()遍历元素。<br />
2、<font color="#3366ff">Set</font>和Collection拥有一模一样的接口。<br />
3、<font color="#3366ff">List</font>，<font color="#3366ff">可以通过get()方法来一次取出一个元素</font>。使用数字来选择一堆对象中的一个，get(0)...。(add/get)<br />
4、一般使用ArrayList。<font color="#3366ff">用LinkedList构造堆栈stack、队列queue</font>。</p>
<br />
<p>5、<font color="#3366ff">Map用 put(k,v) / get(k)</font>，还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HashMap会利用对象的hashCode来快速找到key。<br />
&nbsp;&nbsp;&nbsp;&nbsp;<strong>*&nbsp;&nbsp;&nbsp;&nbsp; hashing<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 哈希码就是将对象的信息经过一些转变形成一个独一无二的int值，这个值存储在一个array中。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们都知道所有存储结构中，array查找速度是最快的。所以，可以加速查找。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发生碰撞时，让array指向多个values。即，数组每个位置上又生成一个梿表。</p>
<br />
<p><strong><font color="#3366ff">6、Map中元素，可以将key序列、value序列单独抽取出来。<br />
</font></strong>使用<font color="#0000ff">keySet()</font>抽取key序列，将map中的所有keys生成一个Set。<br />
使用<font color="#3366ff"><font color="#0000ff">values(</font>)</font>抽取value序列，将map中的所有values生成一个Collection。</p>
<br />
<p>为什么一个生成Set，一个生成Collection？那是因为，key总是独一无二的，value允许重复。</p>
 <img src ="http://www.blogjava.net/cyantide/aggbug/213528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cyantide/" target="_blank">cyantide</a> 2008-07-09 10:02 <a href="http://www.blogjava.net/cyantide/archive/2008/07/09/213528.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>