??xml version="1.0" encoding="utf-8" standalone="yes"?>国产一区亚洲一区,一区二区三区四区激情,中文字幕日韩一区二区http://www.aygfsteel.com/asklxf/category/5513.htmlA java developer's notebook.zh-cnFri, 02 Mar 2007 02:54:23 GMTFri, 02 Mar 2007 02:54:23 GMT60JDK源码分析Qjava.lang.Booleanhttp://www.aygfsteel.com/asklxf/articles/22201.htmlXuefeng's WeblogXuefeng's WeblogFri, 02 Dec 2005 02:35:00 GMThttp://www.aygfsteel.com/asklxf/articles/22201.htmlhttp://www.aygfsteel.com/asklxf/comments/22201.htmlhttp://www.aygfsteel.com/asklxf/articles/22201.html#Feedback0http://www.aygfsteel.com/asklxf/comments/commentRss/22201.htmlhttp://www.aygfsteel.com/asklxf/services/trackbacks/22201.html闲来无事Q开始研IJDK源码Qjdk 1.5 b2Q,先找了一个最单的java.lang.Boolean开始解剖?BR>
׃水^有限Q难免有不少错误Q还请大家指正!

首先我们剔除所有的Ҏ(gu)和静态变量,Boolean的核心代码如下:

public final class Boolean implements java.io.Serializable,Comparable
{
    private final boolean value;
}

很明显,凡是成员变量都是finalcd的,一定是immutable classQ这个Boolean和String一P一旦构造函数执行完毕,实例的状态就不能再改变了?BR>
Boolean的构造函数有两个Q?/P>

public Boolean(boolean value) {
    this.value = value;
}
public Boolean(String s) {
    this(toBoolean(s));
}

都很单就不多说了?BR>
另外注意到Booleancd际上只有两种不同状态的实例Q一个包装trueQ一个包装f(xi)alseQBoolean又是immutable classQ所以在内存中相同状态的Boolean实例完全可以׃nQ不必用new创徏很多实例。因此Boolean classq提供两个静态变量:

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

q两个变量在Class Loader装蝲时就被实例化Qƈ且申明ؓfinalQ不能再指向其他实例?BR>
提供q两个静态变量是Z让开发者直接用这两个变量而不是每ơ都new一个BooleanQ这h节省内存又避免了创徏一个新实例的时间开销?BR>
因此Q用
    Boolean b = Boolean.TRUE;
?BR>    Boolean b = new Boolean(true);
要好得多?BR>
如果遇到下面的情况:
    Boolean b = new Boolean(var);
一定要Ҏ(gu)一个boolean变量来创建Boolean实例怎么办?

推荐你用Boolean提供的静态工厂方法:
    Boolean b = Boolean.valueOf(var);
q样可以避免创建新的实例,不信看看valueOf()静态方法:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

q个静态工厂方法返回的仍然是两个静态变量TRUE和FALSE之一Q而不是new一个Boolean出来。虽然Boolean非常单,占用的内存也很少Q但是一个复杂的cȝnew创徏实例的开销可能非常大,而且Q用工厂方法可以方便的实现~存实例Q这对客L(fng)是透明的。所以,能用工厂Ҏ(gu)׃要用new?BR>
和Boolean只有两种状态不同,Integer也是immutable classQ但是状态上亿种Q不可能用静态实例缓存所有状态。不q,SUN的工E师q是作了一点优化,Integercȝ存了-128?27q?56个状态的IntegerQ如果用Integer.valueOf(int i)Q传入的int范围正好在此内,p回静态实例?BR>
hashCode()Ҏ(gu)很奇怪,两种Boolean的hash code分别?231?237。估计写Boolean.java的h对这两个数字有特别偏好:

public int hashCode() {
    return value ? 1231 : 1237;
}

equals()Ҏ(gu)也很单,只有Booleancd的Objectq且value相等才返trueQ?/P>

public boolean equals(Object obj) {
    if (obj instanceof Boolean) {
        return value == ((Boolean)obj).booleanValue();
    }
    return false;
}

Z提一句:很多人写equals()L在第一行写Q?BR>   if (obj==null) return false;
其实完全没有必要Q因为如果obj==nullQ下一行的
    if (obj instanceof Type)
p定返回falseQ因?null instanceof AnyType) = false?BR>详细内容请参考《Effective Java》第7条:Obey the general contract when overriding equals?BR>
其他的方法如toString()更单了Q只要稍微熟(zhn)java的程序员怿都能写出来,我就不多说了?BR>
?/FONT> ȝ ?/FONT>

1.如果一个类只有有限的几U状态,考虑用几个final的静态变量来表示不同状态的实例?BR>例如~写一个Weekdayc,状态只?个,׃要让用户写new Weekday(1)Q直接提供Weekday.MONDAY卛_?BR>
2.要防止用户用new生成实例Q就取消public构造函敎ͼ用户要获得静态实例的引用有两个方法:如果xpublic static var可以直接访问,比如Boolean.TRUEQ?BR>W二个方法是通过静态工厂方法:Boolean.valueOf(?)

3.如果不提供public构造函敎ͼ让用户只能通过上面的方法获得静态变量的引用Q还可以大大化equals()Ҏ(gu)Q?BR>    public boolean equals(Object obj) {
        return this==obj;
    }
可以直接?=比较引用Q绝Ҏ(gu)有问题,而且效率最高?BR>
4.Z么JDK的Boolean没有实现上面W?点?因ؓ那两个static变量TRUE和FALSE是在jdk 1.2以后才有的,׃前面的版本已l把构造函数申明ؓpublicQ所以ؓ了保持客L(fng)代码能够不修改也在后面的版本中运行,只好l箋提供public构造函数?/P>

Xuefeng's Weblog 2005-12-02 10:35 发表评论
]]>
RMI调用模版http://www.aygfsteel.com/asklxf/articles/22200.htmlXuefeng's WeblogXuefeng's WeblogFri, 02 Dec 2005 02:34:00 GMThttp://www.aygfsteel.com/asklxf/articles/22200.htmlhttp://www.aygfsteel.com/asklxf/comments/22200.htmlhttp://www.aygfsteel.com/asklxf/articles/22200.html#Feedback0http://www.aygfsteel.com/asklxf/comments/commentRss/22200.htmlhttp://www.aygfsteel.com/asklxf/services/trackbacks/22200.html1. 定义q程接口 

// q程接口l承?/SPAN>Remote

// q程Ҏ(gu)的传入参数和q回值必L自然cdQ?/SPAN>intQ?/SPAN>floatQ?/SPAN>boolean{)

// 或者实CSerializable?/SPAN>Remote接口的对象?/SPAN>

public interface Time extends java.rmi.Remote {

    // q程Ҏ(gu)必须抛出RemoteExceptionQ?/SPAN>

    public String getTime() throws RemoteException;

}

 

2. 定义实现c?/SPAN> 

// 注意Q实现类l承?/SPAN>UnicastRemoteObject和自定义的远E接?/SPAN>TimeQ?/SPAN>

public class TimeImpl extends java.rmi.server.UnicastRemoteObject implements Time {

    // 注意Q由?/SPAN>RemoteObject构造函数要抛出RemoteExceptionQ?/SPAN>

    // 因此务必定义构造函数ƈ抛出RemoteExceptionQ?/SPAN>

    public TimeImpl() throws RemoteException { super(); }

 

    // q里是远E方法:

    public String getTime() throws RemoteException {

        return "12:04:27";

    }

 

    // 启动服务Q?/SPAN>

    public static void main(String[] args) throws Exception {

        // 可以手动启动RMI RegistryQ也可以在程序中启动Q?/SPAN>

        java.rmi.registry.LocateRegistry.createRegistry(1099);

        // l定名字服务Q地址是本地计机名或本机IPQ默认端口是1099Q?/SPAN>

        java.rmi.Naming.bind("http://localhost:1099/servicename", new TimeImpl());

        // 如果没有异常抛出Q则l定成功?/SPAN>

        // 如果名字已经被绑定,可以?/SPAN>Naming.rebind()替换掉已l定的服务?/SPAN>

    }

}

 

3. ~译生成桩和框架 

q行rmic TimeImplQ生?/SPAN>TimeImpl_Skel.class?/SPAN>TimeImpl_Stub.class?/SPAN>

 

4. 客户?/SPAN>

// 客户端文件包含客L(fng)代码Client.classQ远E接?/SPAN>Time.classQ?/SPAN>

// ?/SPAN>rmic生成的支持类TimeImpl_Skel.class?/SPAN>TimeImpl_Stub.classQ?/SPAN>

public static void main(String[] args) throws Exception {

    // 客户端通过IP引用服务器端的远E对象,因此可以动态选择服务器?/SPAN>

    // 如果不指定端口,默认端口h1099Q?/SPAN>

    Time time = (Time)java.rmi.Naming.lookup("http://localhost:1099/servicename");

    System.out.println(time.getTime());

}



]]>
l说Java之utilc?/title><link>http://www.aygfsteel.com/asklxf/articles/22195.html</link><dc:creator>Xuefeng's Weblog</dc:creator><author>Xuefeng's Weblog</author><pubDate>Fri, 02 Dec 2005 02:29:00 GMT</pubDate><guid>http://www.aygfsteel.com/asklxf/articles/22195.html</guid><wfw:comment>http://www.aygfsteel.com/asklxf/comments/22195.html</wfw:comment><comments>http://www.aygfsteel.com/asklxf/articles/22195.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/asklxf/comments/commentRss/22195.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/asklxf/services/trackbacks/22195.html</trackback:ping><description><![CDATA[<P>  U性表Q链表,哈希表是常用的数据结构,在进行Java开发时QJDK已经为我们提供了一pd相应的类来实现基本的数据l构。这些类均在java.util包中。本文试N过单的描述Q向读者阐q各个类的作用以及如何正用这些类?</P> <P><EM>Collection</EM><BR>?EM>List</EM><BR>│├LinkedList<BR>│├ArrayList<BR>│└Vector<BR>│ └Stack<BR>?EM>Set</EM><BR><EM>Map</EM><BR>├Hashtable<BR>├HashMap<BR>└WeakHashMap</P> <P><STRONG><FONT color=#0000ff>Collection接口</FONT></STRONG><BR>  Collection是最基本的集合接口,一个Collection代表一lObjectQ即Collection的元素(ElementsQ。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接承自Collection的类QJava SDK提供的类都是l承自Collection的“子接口”如List和Set?BR>  所有实现Collection接口的类都必L供两个标准的构造函敎ͼ无参数的构造函数用于创Z个空的CollectionQ有一个Collection参数的构造函数用于创Z个新的CollectionQ这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection?BR>  如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个P代子Q用该q代子即可逐一讉KCollection中每一个元素。典型的用法如下Q?BR><FONT face="Courier New" color=#336666>    Iterator it = collection.iterator(); // 获得一个P代子<BR>    while(it.hasNext()) {<BR>      Object obj = it.next(); // 得到下一个元?BR>    }</FONT><BR>  由Collection接口z的两个接口是List和Set?/P> <P><FONT color=#0000ff><STRONG>List接口</STRONG></FONT><BR>  List是有序的CollectionQ用此接口能够_的控制每个元素插入的位置。用戯够用烦引(元素在List中的位置Q类g数组下标Q来讉KList中的元素Q这cM于Java的数l?BR>和下面要提到的Set不同QList允许有相同的元素?BR>  除了hCollection接口必备的iterator()Ҏ(gu)外,Listq提供一个listIterator()Ҏ(gu)Q返回一个ListIterator接口Q和标准的Iterator接口相比QListIterator多了一些add()之类的方法,允许dQ删除,讑֮元素Q还能向前或向后遍历?BR>  实现List接口的常用类有LinkedListQArrayListQVector和Stack?/P> <P><FONT color=#0000ff><STRONG>LinkedListc?/STRONG></FONT><BR>  LinkedList实现了List接口Q允许null元素。此外LinkedList提供额外的getQremoveQinsertҎ(gu)在LinkedList的首部或N。这些操作LinkedList可被用作堆栈QstackQ,队列QqueueQ或双向队列QdequeQ?BR>  注意LinkedList没有同步Ҏ(gu)。如果多个线E同时访问一个ListQ则必须自己实现讉K同步。一U解x法是在创建List时构造一个同步的ListQ?BR><FONT face="Courier New" color=#336666>    List list = Collections.synchronizedList(new LinkedList(...));</FONT></P> <P><FONT color=#0000ff><STRONG>ArrayListc?/STRONG></FONT><BR>  ArrayList实现了可变大的数组。它允许所有元素,包括null。ArrayList没有同步?BR>sizeQisEmptyQgetQsetҎ(gu)q行旉为常数。但是addҎ(gu)开销为分摊的常数Q添加n个元素需要O(n)的时间。其他的Ҏ(gu)q行旉为线性?BR>  每个ArrayList实例都有一个容量(CapacityQ,即用于存储元素的数组的大。这个容量可随着不断d新元素而自动增加,但是增长法q没有定义。当需要插入大量元素时Q在插入前可以调用ensureCapacityҎ(gu)来增加ArrayList的容量以提高插入效率?BR>  和LinkedList一PArrayList也是非同步的QunsynchronizedQ?/P> <P><FONT color=#0000ff><STRONG>Vectorc?/STRONG></FONT><BR>  Vector非常cMArrayListQ但是Vector是同步的。由Vector创徏的IteratorQ虽然和ArrayList创徏的Iterator是同一接口Q但是,因ؓVector是同步的Q当一个Iterator被创且正在被用,另一个线E改变了Vector的状态(例如Q添加或删除了一些元素)Q这时调用Iterator的方法时抛出ConcurrentModificationExceptionQ因此必L莯异常?/P> <P><STRONG><FONT color=#0000ff>Stack c?/FONT></STRONG><BR>  Stackl承自VectorQ实C个后q先出的堆栈。Stack提供5个额外的Ҏ(gu)使得Vector得以被当作堆栈用。基本的push和popҎ(gu)Q还有peekҎ(gu)得到栈顶的元素,emptyҎ(gu)试堆栈是否为空QsearchҎ(gu)一个元素在堆栈中的位置。Stack刚创建后是空栈?/P> <P><FONT color=#0000ff><STRONG>Set接口</STRONG></FONT><BR>  Set是一U不包含重复的元素的CollectionQ即L的两个元素e1和e2都有e1.equals(e2)=falseQSet最多有一个null元素?BR>  很明显,Set的构造函数有一个约束条Ӟ传入的Collection参数不能包含重复的元素?BR>  h意:必须心操作可变对象QMutable ObjectQ。如果一个Set中的可变元素改变了自w状态导致Object.equals(Object)=true导致一些问题?/P> <P><FONT color=#0000ff><STRONG>Map接口</STRONG></FONT><BR>  h意,Map没有l承Collection接口QMap提供key到value的映。一个Map中不能包含相同的keyQ每个key只能映射一个value。Map接口提供3U集合的视图QMap的内容可以被当作一lkey集合Q一lvalue集合Q或者一lkey-value映射?/P> <P><FONT color=#0000ff><STRONG>Hashtablec?/STRONG></FONT><BR>  Hashtablel承Map接口Q实C个key-value映射的哈希表。Q何非I(non-nullQ的对象都可作ؓkey或者value?BR>  d数据使用put(key, value)Q取出数据用get(key)Q这两个基本操作的时间开销为常数?BR>Hashtable通过initial capacity和load factor两个参数调整性能。通常~省的load factor 0.75较好地实C旉和空间的均衡。增大load factor可以节省I间但相应的查找旉增大,q会影响像get和putq样的操作?BR>使用Hashtable的简单示例如下,?Q?Q?攑ֈHashtable中,他们的key分别是”one”,”two”,”three”:<BR><FONT face="Courier New" color=#336666>    Hashtable numbers = new Hashtable();<BR>    numbers.put(“one? new Integer(1));<BR>    numbers.put(“two? new Integer(2));<BR>    numbers.put(“three? new Integer(3));</FONT><BR>  要取Z个数Q比?Q用相应的keyQ?BR><FONT face="Courier New" color=#336666>    Integer n = (Integer)numbers.get(“two?;<BR>    System.out.println(“two = ?+ n);</FONT><BR>  ׃作ؓkey的对象将通过计算其散列函数来定与之对应的value的位|,因此M作ؓkey的对象都必须实现hashCode和equalsҎ(gu)。hashCode和equalsҎ(gu)l承自根cObjectQ如果你用自定义的类当作key的话Q要相当心Q按照散列函数的定义Q如果两个对象相同,即obj1.equals(obj2)=trueQ则它们的hashCode必须相同Q但如果两个对象不同Q则它们的hashCode不一定不同,如果两个不同对象的hashCode相同Q这U现象称为冲H,冲突会导致操作哈希表的时间开销增大Q所以尽量定义好的hashCode()Ҏ(gu)Q能加快哈希表的操作?BR>  如果相同的对象有不同的hashCodeQ对哈希表的操作会出现意想不到的l果Q期待的getҎ(gu)q回nullQ,要避免这U问题,只需要牢C条:要同时复写equalsҎ(gu)和hashCodeҎ(gu)Q而不要只写其中一个?BR>  Hashtable是同步的?/P> <P><STRONG><FONT color=#0000ff>HashMapc?/FONT></STRONG><BR>  HashMap和HashtablecMQ不同之处在于HashMap是非同步的,q且允许nullQ即null value和null key。,但是HashMap视ؓCollectionӞvalues()Ҏ(gu)可返回CollectionQ,其P代子操作旉开销和HashMap的容量成比例。因此,如果q代操作的性能相当重要的话Q不要将HashMap的初始化定w讑־q高Q或者load factorq低?/P> <P><FONT color=#0000ff><STRONG>WeakHashMapc?/STRONG></FONT><BR>  WeakHashMap是一U改q的HashMapQ它对key实行“弱引用”,如果一个key不再被外部所引用Q那么该key可以被GC回收?/P> <P><FONT color=#ff0000><STRONG>ȝ</STRONG></FONT><BR>  如果涉及到堆栈,队列{操作,应该考虑用ListQ对于需要快速插入,删除元素Q应该用LinkedListQ如果需要快速随问元素,应该使用ArrayList?BR>  如果E序在单U程环境中,或者访问仅仅在一个线E中q行Q考虑非同步的c,其效率较高,如果多个U程可能同时操作一个类Q应该用同步的cR?BR>  要特别注意对哈希表的操作Q作为key的对象要正确复写equals和hashCodeҎ(gu)?BR>  量q回接口而非实际的类型,如返回List而非ArrayListQ这样如果以后需要将ArrayList换成LinkedListӞ客户端代码不用改变。这是针对抽象~程?/P> <P align=right>Q参考:Sun JDK1.4.1 API DOCQ?/P><img src ="http://www.aygfsteel.com/asklxf/aggbug/22195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/asklxf/" target="_blank">Xuefeng's Weblog</a> 2005-12-02 10:29 <a href="http://www.aygfsteel.com/asklxf/articles/22195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Į</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">°Ͷ</a>| <a href="http://" target="_blank">ͨ</a>| <a href="http://" target="_blank">Ƿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϻ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ȫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ν</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">γ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӱ</a>| <a href="http://" target="_blank">ᶫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">½</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">׺</a>| <a href="http://" target="_blank">Ͷ</a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>