<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shadow &#38; Honnix &#187; Java</title>
	<atom:link href="http://honnix.com/blog/archives/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://honnix.com/blog</link>
	<description>she&#039;s growing up</description>
	<lastBuildDate>Sun, 15 Jan 2012 10:44:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Java调用Scala的一个真实案例</title>
		<link>http://honnix.com/blog/archives/750</link>
		<comments>http://honnix.com/blog/archives/750#comments</comments>
		<pubDate>Fri, 12 Aug 2011 15:26:23 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[conversion]]></category>
		<category><![CDATA[invoke]]></category>
		<category><![CDATA[调用]]></category>
		<category><![CDATA[转换]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=750</guid>
		<description><![CDATA[Scala调用Java，完全没有问题；但是反过来总有那么一点不爽，或者必须要修改。这里是项目中一个真实的案例，拿出来分享一下。 1. 类型转换 1 2 3 4 5 object AsnLoader &#123; ... def batchLoadFile&#40;files: List&#91;String&#93;&#41;: Map&#91;String, AsnModule&#93; = files.foldLeft&#40;Map&#91;String, AsnModule&#93;&#40;&#41;&#41;&#40;&#40;x, y&#41; =&#62; x ++ load&#40;y&#41;&#41; ... &#125; 这里的List是Scala里的类，从Java里面调这个方法是不行的，所以需要弄一个wrapper方法： 1 2 3 import collection.JavaConversions._ ... def batchLoadFile&#40;files: java.util.List&#91;String&#93;&#41;: java.util.Map&#91;String, AsnModule&#93; = batchLoadFile&#40;asScalaBuffer&#40;files&#41;.toList&#41; 虽然asScalaBuffer本身就是个implicit，但是这里仍需要显示调用一下，否则编译器会认为batchLoadFile(file: java.util.List[String])更符合调用匹配规则，结果就变成了无限递归…… Java里面这样调用： 1 AsnLoader.batchLoadFile&#40;list&#41;; 这样看起来解决问题了，但是Eclipse的Scala插件会报一个莫名其妙的函数签名错误，其实根本就没错，直接maven或者用Intellij都是对的，Eclipse插件太烂或者太老。无奈只好把函数名也一起改了：batchLoadFileJ，这样就可以了。如果还不是很明白，去看看JavaConversions里面的implicit。 把Java的Map转换成Scala的immutale map稍微曲折了些，先转换成mutable map，再调用toMap方法转换成immutable map。 2. 构造方法 1 2&#8230;]]></description>
			<content:encoded><![CDATA[<p>Scala调用Java，完全没有问题；但是反过来总有那么一点不爽，或者必须要修改。这里是项目中一个真实的案例，拿出来分享一下。</p>
<p>1. 类型转换</p>

<div class="wp_codebox"><table><tr id="p7507"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p750code7"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> AsnLoader <span style="color: #F78811;">&#123;</span>
  ...
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> batchLoadFile<span style="color: #F78811;">&#40;</span>files<span style="color: #000080;">:</span> List<span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Map<span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span> files.<span style="color: #000000;">foldLeft</span><span style="color: #F78811;">&#40;</span>Map<span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span>x, y<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> x ++ load<span style="color: #F78811;">&#40;</span>y<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>
  ...
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>这里的List是Scala里的类，从Java里面调这个方法是不行的，所以需要弄一个wrapper方法：</p>

<div class="wp_codebox"><table><tr id="p7508"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p750code8"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> collection.<span style="color: #000000;">JavaConversions</span>.<span style="color: #000080;">_</span>
...
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> batchLoadFile<span style="color: #F78811;">&#40;</span>files<span style="color: #000080;">:</span> java.<span style="color: #000000;">util</span>.<span style="color: #000000;">List</span><span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> java.<span style="color: #000000;">util</span>.<span style="color: #000000;">Map</span><span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span> batchLoadFile<span style="color: #F78811;">&#40;</span>asScalaBuffer<span style="color: #F78811;">&#40;</span>files<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">toList</span><span style="color: #F78811;">&#41;</span></pre></td></tr></table></div>

<p>虽然asScalaBuffer本身就是个implicit，但是这里仍需要显示调用一下，否则编译器会认为batchLoadFile(file: java.util.List[String])更符合调用匹配规则，结果就变成了无限递归……</p>
<p>Java里面这样调用：</p>

<div class="wp_codebox"><table><tr id="p7509"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p750code9"><pre class="scala" style="font-family:monospace;">AsnLoader.<span style="color: #000000;">batchLoadFile</span><span style="color: #F78811;">&#40;</span>list<span style="color: #F78811;">&#41;</span><span style="color: #000080;">;</span></pre></td></tr></table></div>

<p>这样看起来解决问题了，但是Eclipse的Scala插件会报一个莫名其妙的函数签名错误，其实根本就没错，直接maven或者用Intellij都是对的，Eclipse插件太烂或者太老。无奈只好把函数名也一起改了：batchLoadFileJ，这样就可以了。如果还不是很明白，去看看JavaConversions里面的implicit。</p>
<p>把Java的Map转换成Scala的immutale map稍微曲折了些，先转换成mutable map，再调用toMap方法转换成immutable map。</p>
<p>2. 构造方法</p>

<div class="wp_codebox"><table><tr id="p75010"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p750code10"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> DefaultTransformer<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> asnModule<span style="color: #000080;">:</span> AsnModule, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> dependencies<span style="color: #000080;">:</span> Map<span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span> Map.<span style="color: #000000;">empty</span>,
                         <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> repository<span style="color: #000080;">:</span> Map<span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span> <span style="color: #000080;">=</span> Map.<span style="color: #000000;">empty</span>,
                         <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> messageHandler<span style="color: #000080;">:</span> MessageHandler <span style="color: #000080;">=</span> ConsoleMessageHandler<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">false</span></a><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
  ...
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>这里面的Map都是Scala的Map，所以从Java里不能直接调用，而Scala的构造方法又比较特别，重载的话只能减少参数个数而不能改变类型。这时候就需要companion object上场了。</p>

<div class="wp_codebox"><table><tr id="p75011"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p750code11"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> DefaultTransformer <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>asnModule<span style="color: #000080;">:</span> AsnModule,
                 dependencies<span style="color: #000080;">:</span> java.<span style="color: #000000;">util</span>.<span style="color: #000000;">Map</span><span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span>,
                 repository<span style="color: #000080;">:</span> java.<span style="color: #000000;">util</span>.<span style="color: #000000;">Map</span><span style="color: #F78811;">&#91;</span>String, AsnModule<span style="color: #F78811;">&#93;</span>,
                 messageHandler<span style="color: #000080;">:</span> MessageHandler<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> DefaultTransformer<span style="color: #F78811;">&#40;</span>asnModule, dependencies, repository, messageHandler<span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>Java这样调用：</p>

<div class="wp_codebox"><table><tr id="p75012"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p750code12"><pre class="scala" style="font-family:monospace;">Transformer transformer <span style="color: #000080;">=</span> DefaultTransformer.<span style="color: #000000;">apply</span><span style="color: #F78811;">&#40;</span>...<span style="color: #F78811;">&#41;</span><span style="color: #000080;">;</span></pre></td></tr></table></div>

<p>3. Scala的bug</p>
<p>嗯，XML在什么语言里都是让人恶心的东西，即使Scala已经尽力做好了：<a href="https://issues.scala-lang.org/browse/SI-4865">https://issues.scala-lang.org/browse/SI-4865</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/750/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JRuby和Java的互操作</title>
		<link>http://honnix.com/blog/archives/742</link>
		<comments>http://honnix.com/blog/archives/742#comments</comments>
		<pubDate>Wed, 22 Jun 2011 15:05:42 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[interoperation]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[调用]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=742</guid>
		<description><![CDATA[我试图让新的BL框架支持所有流行的JVM语言。Scala很简单，天衣无缝，但是Ruby和Python就比较周折了。不谈Python，先看看Ruby，确切地说是JRuby。 jrubyc可以把一个Ruby的class编译成Java的，看看下面的例子： Bar.java 1 2 3 4 5 package com.honnix.foo; &#160; interface Bar &#123; int getValue&#40;&#41;; &#125; BarImpl.rb 1 2 3 4 5 6 7 8 9 10 11 java_package 'com.honnix.foo' require 'java' &#160; class BarImpl include Java::com.honnix.foo.Bar &#160; java_signature 'int getValue()' def get&#40;&#41; 1 end end > javac Bar.java > jrubyc --javac -cp com.honnix.foo&#8230;]]></description>
			<content:encoded><![CDATA[<p>我试图让新的BL框架支持所有流行的JVM语言。Scala很简单，天衣无缝，但是Ruby和Python就比较周折了。不谈Python，先看看Ruby，确切地说是JRuby。</p>
<p>jrubyc可以把一个Ruby的class编译成Java的，看看下面的例子：</p>
<p>Bar.java</p>

<div class="wp_codebox"><table><tr id="p74215"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p742code15"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.honnix.foo</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span> Bar <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span> getValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>BarImpl.rb</p>

<div class="wp_codebox"><table><tr id="p74216"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p742code16"><pre class="ruby" style="font-family:monospace;">java_package <span style="color:#996600;">'com.honnix.foo'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'java'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> BarImpl
  <span style="color:#9966CC; font-weight:bold;">include</span> Java::com.<span style="color:#9900CC;">honnix</span>.<span style="color:#9900CC;">foo</span>.<span style="color:#9900CC;">Bar</span>
&nbsp;
  java_signature <span style="color:#996600;">'int getValue()'</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> get<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#006666;">1</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><code>> javac Bar.java</code><br />
<code>> jrubyc --javac -cp com.honnix.foo BarImpl.rb</code></p>
<p>这样基本上就差不多了。</p>
<p>不过看看生产的Java代码，就知道这样玩儿的效率恐怕成问题。其实就是先build出来一个Ruby代码的巨大字符串，然后给交给Ruby引擎去跑，最后返回结果。</p>
<p>不管怎么说，只是这是一个方案，接下来就是要考虑怎么把Java的Document转成Ruby喜欢的格式，再转回来。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/742/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java的范型方法</title>
		<link>http://honnix.com/blog/archives/740</link>
		<comments>http://honnix.com/blog/archives/740#comments</comments>
		<pubDate>Fri, 03 Jun 2011 13:06:00 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[generic method]]></category>
		<category><![CDATA[范型]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=740</guid>
		<description><![CDATA[Java的范型一直让我头疼，也一直没仔细研究，总之感觉不好用。这两天折腾了一下，把范型方法整明白了。 一个简单的例子： 1 2 3 4 private static &#60;T&#62; T test&#40;T a&#41; &#123; Person&#60;T&#62; person = new Person&#60;T&#62;&#40;a&#41;; return person.getName&#40;&#41;; &#125; 调用的时候这样： 1 test&#40;1&#41;; 是不是认为编译器编译的时候会自动将T转换成Integer？我们来看看javap的结果： 1 invokestatic #22; //Method test:(Ljava/lang/Object;)Ljava/lang/Object; 看到什么了？没有Integer，只有Object！ 如果这样设计test()： 1 2 3 4 private static &#60;T extends Number&#62; T test&#40;T a&#41; &#123; Person&#60;T&#62; person = new Person&#60;T&#62;&#40;a&#41;; return person.getName&#40;&#41;; &#125; 结果就是： 1&#8230;]]></description>
			<content:encoded><![CDATA[<p>Java的范型一直让我头疼，也一直没仔细研究，总之感觉不好用。这两天折腾了一下，把范型方法整明白了。</p>
<p>一个简单的例子：</p>

<div class="wp_codebox"><table><tr id="p74023"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p740code23"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span> T test<span style="color: #009900;">&#40;</span>T a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Person<span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span> person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> person.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>调用的时候这样：</p>

<div class="wp_codebox"><table><tr id="p74024"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p740code24"><pre class="java" style="font-family:monospace;">test<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>是不是认为编译器编译的时候会自动将T转换成Integer？我们来看看javap的结果：</p>

<div class="wp_codebox"><table><tr id="p74025"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p740code25"><pre class="java" style="font-family:monospace;">invokestatic	#<span style="color: #cc66cc;">22</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Method test:(Ljava/lang/Object;)Ljava/lang/Object;</span></pre></td></tr></table></div>

<p>看到什么了？没有Integer，只有Object！</p>
<p>如果这样设计test()：</p>

<div class="wp_codebox"><table><tr id="p74026"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p740code26"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #339933;">&lt;</span>T <span style="color: #000000; font-weight: bold;">extends</span> Number<span style="color: #339933;">&gt;</span> T test<span style="color: #009900;">&#40;</span>T a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Person<span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span> person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> person.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>结果就是：</p>

<div class="wp_codebox"><table><tr id="p74027"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p740code27"><pre class="java" style="font-family:monospace;">invokestatic	#<span style="color: #cc66cc;">23</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Method test:(Ljava/lang/Number;)Ljava/lang/Number;</span></pre></td></tr></table></div>

<p>所以是不是可以得出结论，javac根本就不看调用的时候传入什么类型的东西，只看方法定义？</p>
<p>你完全可以这样写：</p>

<div class="wp_codebox"><table><tr id="p74028"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p740code28"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> test<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Person<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span> person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> person.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>只是前者看上去比较牛逼罢了，其实效果完全相同。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/740/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac里面的JDK的源码和javadoc</title>
		<link>http://honnix.com/blog/archives/650</link>
		<comments>http://honnix.com/blog/archives/650#comments</comments>
		<pubDate>Tue, 01 Mar 2011 15:59:00 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[javadoc]]></category>
		<category><![CDATA[JDK]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[src.jar]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=650</guid>
		<description><![CDATA[在Apple还没完全转到OpenJDK之前，他自家的东西还是得用着。不过默认JDK源码和javadoc是不会装的。 到这里下：https://connect.apple.com/，右边找Dowloads-&#62;Java。 需要ADC，没有的话自己注册一个，也不花钱。 10.6 update 2之前是叫Developer Document，update 3之后就叫Developer Package了。找需要的下。装好之后在这里：/Library/Java/JavaVirtualMachines/&#60;version&#62;/Contents/Home。同样是src.jar和docs.jar，另外还有苹果自己的一个appledocs.jar。]]></description>
			<content:encoded><![CDATA[<p>在Apple还没完全转到OpenJDK之前，他自家的东西还是得用着。不过默认JDK源码和javadoc是不会装的。</p>
<p>到这里下：<a href="https://connect.apple.com/" target="_blank">https://connect.apple.com/</a>，右边找Dowloads-&gt;Java。</p>
<p>需要ADC，没有的话自己注册一个，也不花钱。</p>
<p>10.6 update 2之前是叫Developer Document，update 3之后就叫Developer Package了。找需要的下。装好之后在这里：/Library/Java/JavaVirtualMachines/&lt;version&gt;/Contents/Home。同样是src.jar和docs.jar，另外还有苹果自己的一个appledocs.jar。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/650/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>慢慢地转到maven</title>
		<link>http://honnix.com/blog/archives/483</link>
		<comments>http://honnix.com/blog/archives/483#comments</comments>
		<pubDate>Mon, 09 Nov 2009 12:48:16 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[jfetion]]></category>
		<category><![CDATA[libfetion]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[-d32]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[64位]]></category>
		<category><![CDATA[smsd]]></category>
		<category><![CDATA[Snow Leopard]]></category>
		<category><![CDATA[参数]]></category>
		<category><![CDATA[飞信]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=483</guid>
		<description><![CDATA[开始把之前做的一些项目往maven上转了。先是jfetion，再加上今天做的smsd。 说来惭愧，jfetion做了很久了，但是自己一直都没弄个什么应用出来，一直在用的smsd还是最早的时候用C写的。今天老婆出去逛街，闲来无事，用Scala重写了一遍，已经可以正常工作了，其它的功能慢慢加吧。 基本想法很简单，后台启一个daemon，监视某个文件夹，如果里面有.sms文件，就把里面的内容发送给相应的人，当然必须是飞信上面的好友。 顺便说一下，Snow Leopard的Java默认是64位的，而libfetion没有Mac上64位的版本，所以要么在系统设置里面更改Java的默认设置，要么运行的时候给个参数：java -d32 &#8230;]]></description>
			<content:encoded><![CDATA[<p>开始把之前做的一些项目往maven上转了。先是jfetion，再加上今天做的smsd。</p>
<p>说来惭愧，jfetion做了很久了，但是自己一直都没弄个什么应用出来，一直在用的smsd还是最早的时候用C写的。今天老婆出去逛街，闲来无事，用Scala重写了一遍，已经可以正常工作了，其它的功能慢慢加吧。</p>
<p>基本想法很简单，后台启一个daemon，监视某个文件夹，如果里面有.sms文件，就把里面的内容发送给相应的人，当然必须是飞信上面的好友。</p>
<p>顺便说一下，Snow Leopard的Java默认是64位的，而libfetion没有Mac上64位的版本，所以要么在系统设置里面更改Java的默认设置，要么运行的时候给个参数：java -d32 &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/483/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>我是如何用Scala定义新异常类型的</title>
		<link>http://honnix.com/blog/archives/412</link>
		<comments>http://honnix.com/blog/archives/412#comments</comments>
		<pubDate>Sun, 09 Aug 2009 02:41:30 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[Exception]]></category>
		<category><![CDATA[extends]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[override]]></category>
		<category><![CDATA[trait]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=412</guid>
		<description><![CDATA[Scala的构造方法非常灵活（具体怎么个灵活法这里不多说了），但随之而来的是重载构造方法的麻烦。 例如定义新异常类型。一般来说，自己定义的异常都属于checked异常，大都从Exception继承过来，所以也大都需要定义多个构造方法。如果用Java来定义，没什么好说的，重载就行，但是用Scala的话就有点麻烦。Scala规定所有重载的构造方法都必须调用或间接调用默认构造方法，所以必须使用如下的方法。 1 2 3 4 5 class MyException&#40;message: String, cause: Throwable&#41; extends Exception&#40;message, cause&#41; &#123; def this&#40;message: String&#41;: = this&#40;message, null&#41; def this&#40;cause: Throwable&#41;: = this&#40;null, cause&#41; def this: = this&#40;null, null&#41; &#125; 当然，这样是可以工作的，但是仔细看看Throwable的实现就会发现如果传入的cause为null话会导致异常栈的丢失。而且最恶心的是Throwable没有提供相应的setter/getter，我们能做的就是调用构造方法。 所以我就想出了下面的怪招。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19&#8230;]]></description>
			<content:encoded><![CDATA[<p>Scala的构造方法非常灵活（具体怎么个灵活法这里不多说了），但随之而来的是重载构造方法的麻烦。</p>
<p>例如定义新异常类型。一般来说，自己定义的异常都属于checked异常，大都从Exception继承过来，所以也大都需要定义多个构造方法。如果用Java来定义，没什么好说的，重载就行，但是用Scala的话就有点麻烦。Scala规定所有重载的构造方法都必须调用或间接调用默认构造方法，所以必须使用如下的方法。</p>

<div class="wp_codebox"><table><tr id="p41231"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p412code31"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> MyException<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>message, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a>, cause<span style="color: #F78811;">&#41;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #000080;">:</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a>, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></td></tr></table></div>

<p>当然，这样是可以工作的，但是仔细看看Throwable的实现就会发现如果传入的cause为null话会导致异常栈的丢失。而且最恶心的是Throwable没有提供相应的setter/getter，我们能做的就是调用构造方法。<br />
所以我就想出了下面的怪招。</p>

<div class="wp_codebox"><table><tr id="p41232"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code" id="p412code32"><pre class="scala" style="font-family:monospace;"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> SpcException <span style="color: #F78811;">&#123;</span>
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException1<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException2<span style="color: #F78811;">&#40;</span>message<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException3<span style="color: #F78811;">&#40;</span>cause<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
&nbsp;
  <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Exception <span style="color: #000080;">=</span>
    <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> SpcException4<span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">asInstanceOf</span><span style="color: #F78811;">&#91;</span>Exception<span style="color: #F78811;">&#93;</span>
<span style="color: #F78811;">&#125;</span>
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">trait</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException1<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String, cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message, cause<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException2<span style="color: #F78811;">&#40;</span>message<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>message<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException3<span style="color: #F78811;">&#40;</span>cause<span style="color: #000080;">:</span> Throwable<span style="color: #F78811;">&#41;</span>
    <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception<span style="color: #F78811;">&#40;</span>cause<span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException
&nbsp;
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> SpcException4 <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">extends</span></a> Exception <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">with</span></a> SpcException</pre></td></tr></table></div>

<p>基本思想是定义一个trait，然后定义四种异常，每种都从该trait扩展并提供不同的默认构造方法，同时定义一个singleton，提供四种不同的apply方法用来构造四种不同的异常。这样就可以解决之前的问题，虽然不怎么好看。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/412/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>准备发布jfetion了</title>
		<link>http://honnix.com/blog/archives/186</link>
		<comments>http://honnix.com/blog/archives/186#comments</comments>
		<pubDate>Tue, 05 Aug 2008 01:37:38 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[libfetion]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[jfetion]]></category>
		<category><![CDATA[JNI]]></category>
		<category><![CDATA[飞信]]></category>

		<guid isPermaLink="false">http://honnix.com/blog/?p=186</guid>
		<description><![CDATA[昨天把build.xml搞好了，现在可以方便地构建整个库，准备发布了，虽然还没有测完全。有些东西实在是不好测，尤其是要一边在虚拟的Windows上用移动官方的fetion登陆，改东西，一边又要在虚拟的Gentoo上写代码、测试，实在是麻烦。先发布一个alpha版本好了。 现在在上班，晚上回去放上来。]]></description>
			<content:encoded><![CDATA[<p>昨天把build.xml搞好了，现在可以方便地构建整个库，准备发布了，虽然还没有测完全。有些东西实在是不好测，尤其是要一边在虚拟的Windows上用移动官方的fetion登陆，改东西，一边又要在虚拟的Gentoo上写代码、测试，实在是麻烦。先发布一个alpha版本好了。</p>
<p>现在在上班，晚上回去放上来。</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/186/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Java里面的Reference</title>
		<link>http://honnix.com/blog/archives/55</link>
		<comments>http://honnix.com/blog/archives/55#comments</comments>
		<pubDate>Mon, 14 Jan 2008 13:25:08 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Reference]]></category>

		<guid isPermaLink="false">http://honnix.oicp.net:8080/blog/?p=55</guid>
		<description><![CDATA[之前写过一篇关于Java Reference的文章，只放了一个链接；这个星期要开Java的Workshop，所以仔细研究了一把。 首先是对几个Reachable作定义（其实是从Java Doc抄来的，翻得我实在不爽，直接看Java Doc吧） ： Strongly Reachable──一个对象是strongly reachable的，当且仅当它能够被某个线程reach到而不需要通过任何的Reference Object Weakly Reachable──一个对象是weakly reachable的，当且仅当它不是strongly reachable的，而且仅通过Soft Reference就可以被查找到 Phantom Reachable──一个对象是phantom reachable的，当且仅当它既不是strongly reachable的，也不是weakyly reachable的，它已经被finalized了，而且有一些Phantom Reference指向它 Phantom Reference： 如果在ReferenceQueue里面读到了一个Phantom Reference对象，说明该reference的referent已经被finalized了，如果它是finalizable的（这样的话需要两次GC才能在ReferenceQueue里面读到），否则一但referent成为phantom reachable的时候reference就被放入ReferenceQueue中。 实验表明，如果referent是finalizable的话，要经过两次GC之后才能在ReferenQueue里面读到Phantom Reference，第一次GC时，referent被finalized，但Phantom Reference不会被放到队列中。 如果new一个Phantom Reference的时候不传给它一个ReferenceQueue，那这个reference几乎没有任何用处，因为PhantomReference.get()永远返回null。 需要注意的是，GC不会调用PhantomReference.clear()，如果不对它显示地进行clear，那么它所引用到的对象就一直以finalized过的状态待在堆里而不被真正的回收，除非所有指向它的Phantom Reference都被clear了，或者它本身变为unreachable了。这一点和Weak Reference以及Soft Reference都不一样。 Phantom Reference一般用来处理一些cleanup的事情：监视某个对象，如果它被finalized之后，释放资源。例如：一个大的图片对象被finalized之后，那么用来读取和处理它的其它一些资源就可以被释放掉了。 Weak Reference： 如果在ReferenceQueue里面读到了一个Weak Reference对象，并不能说明该reference的referent已经被finalized了 所有对象的finalization都由一个FinalizeQueue来处理，这个queue本身就是一个线程；当GC发现一个对象是Weakly Reachable的时候，就会把它的reference放到ReferenceQueue中，而把这个对象放到FinalizeQueue中；这两个动作的先后顺序我还不是很清楚，但似乎不是特别重要，这里只要知道由这么两件事情应该就足够了 GC会主动调用WeakReference.clear()，这一点和Soft Reference相同。这样，即使没有ReferenceQueue我们也可以知道一个对象什么时候被GC发现成为weakly reachable，只要WeakReference.get() == null就可以了。 Weak Reference一般用来实现一些容器，我们不需要对容器的引用显示地清理（container[i] = null）以防止内存泄露。比较有名就是JDK中的WeakHashMap，它的key是Weak Reference，当key成为weakly reachable的时候，key&#38;value在就会被清除出去。这样一来，我们可以用map保存对象引用，以及它的一些附加信息，当这样对象不再是strongly reachable的时候，我们不必手工清理map，一切都交给GC去做了。&#8230;]]></description>
			<content:encoded><![CDATA[<p>之前写过一篇关于Java Reference的文章，只放了一个链接；这个星期要开Java的Workshop，所以仔细研究了一把。</p>
<p><span id="more-55"></span></p>
<p>首先是对几个Reachable作定义（其实是从Java Doc抄来的，翻得我实在不爽，直接看Java Doc吧） ：</p>
<ol>
<li>Strongly Reachable──一个对象是strongly reachable的，当且仅当它能够被某个线程reach到而不需要通过任何的Reference Object</li>
<li>Weakly Reachable──一个对象是weakly reachable的，当且仅当它不是strongly reachable的，而且仅通过Soft Reference就可以被查找到</li>
<li>Phantom Reachable──一个对象是phantom reachable的，当且仅当它既不是strongly reachable的，也不是weakyly reachable的，它已经被finalized了，而且有一些Phantom Reference指向它</li>
</ol>
<p><u>Phantom Reference</u>：</p>
<ul>
<li>如果在ReferenceQueue里面读到了一个Phantom  Reference对象，说明该reference的referent已经被finalized了，如果它是finalizable的（这样的话需要两次GC才能在ReferenceQueue里面读到），否则一但referent成为phantom reachable的时候reference就被放入ReferenceQueue中。</li>
<li>实验表明，如果referent是finalizable的话，要经过两次GC之后才能在ReferenQueue里面读到Phantom Reference，第一次GC时，referent被finalized，但Phantom Reference不会被放到队列中。</li>
<li>如果new一个Phantom Reference的时候不传给它一个ReferenceQueue，那这个reference几乎没有任何用处，因为PhantomReference.get()永远返回null。</li>
<li>需要注意的是，GC不会调用PhantomReference.clear()，如果不对它显示地进行clear，那么它所引用到的对象就一直以finalized过的状态待在堆里而不被真正的回收，除非所有指向它的Phantom Reference都被clear了，或者它本身变为unreachable了。<font color="#ff0000">这一点和Weak Reference以及Soft Reference都不一样。</font></li>
<li>Phantom Reference一般用来处理一些cleanup的事情：监视某个对象，如果它被finalized之后，释放资源。例如：一个大的图片对象被finalized之后，那么用来读取和处理它的其它一些资源就可以被释放掉了。</li>
</ul>
<p><u>Weak Reference</u>：</p>
<ul>
<li> 如果在ReferenceQueue里面读到了一个Weak Reference对象，并不能说明该reference的referent已经被finalized了</li>
<li>所有对象的finalization都由一个FinalizeQueue来处理，这个queue本身就是一个线程；当GC发现一个对象是Weakly Reachable的时候，就会把它的reference放到ReferenceQueue中，而把这个对象放到FinalizeQueue中；这两个动作的先后顺序我还不是很清楚，但似乎不是特别重要，这里只要知道由这么两件事情应该就足够了</li>
<li>GC会主动调用WeakReference.clear()，<font color="#ff0000">这一点和Soft Reference相同。<font color="#000000">这样，即使没有ReferenceQueue我们也可以知道一个对象什么时候被GC发现成为weakly reachable，只要WeakReference.get() == null就可以了。</font></font></li>
<li><font color="#ff0000"><font color="#000000">Weak Reference一般用来实现一些容器，我们不需要对容器的引用显示地清理（container[i] = null）以防止内存泄露。比较有名就是JDK中的WeakHashMap，它的key是Weak Reference，当key成为weakly reachable的时候，key&amp;value在就会被清除出去。这样一来，我们可以用map保存对象引用，以及它的一些附加信息，当这样对象不再是strongly reachable的时候，我们不必手工清理map，一切都交给GC去做了。</font></font></li>
</ul>
<p><u>Soft Reference</u>：</p>
<ul>
<li>Soft Reference和Weak Reference非常类似，只有一点最大的区别：当一个对象变成Soft Reachable状态的时候，它不一定被GC回收（或者说有很大可能不会被回收），具体行为由虚拟机实现决定，唯一能保证的是，在虚拟机抛出OutOfMemory异常之前，这个对象肯定已经被回收了。</li>
<li>Soft Reference的这个特定使得它非常适合做cache，用Soft Reference引用一个大对象，这个对象在某些时候是strongly reachable的，而有些时候又不需要，那么由虚拟机来确定什么时候回收它吧，如果它被回收，那么SoftReference.get()出来的东西就是null，这时候只要再重新实例化一个对象就可以了。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/55/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java的Reference</title>
		<link>http://honnix.com/blog/archives/41</link>
		<comments>http://honnix.com/blog/archives/41#comments</comments>
		<pubDate>Sun, 16 Dec 2007 10:34:01 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://honnix.oicp.net:8080/blog/?p=41</guid>
		<description><![CDATA[很惭愧，自己对Java里面的各种refernce一直不是很明白。今天研究JNI的时候看到了这篇文章，讲得比较清晰，拿来引用一下吧：http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html]]></description>
			<content:encoded><![CDATA[<p>很惭愧，自己对Java里面的各种refernce一直不是很明白。今天研究JNI的时候看到了这篇文章，讲得比较清晰，拿来引用一下吧：<a href="http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html" target="_blank">http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/41/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>鬼知道Eclipse怎么想的</title>
		<link>http://honnix.com/blog/archives/39</link>
		<comments>http://honnix.com/blog/archives/39#comments</comments>
		<pubDate>Thu, 13 Dec 2007 03:21:47 +0000</pubDate>
		<dc:creator>honnix</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://honnix.oicp.net:8080/blog/?p=39</guid>
		<description><![CDATA[为什么把默认的class输出目录改成bin？这么好的名字被污染了。目录命名空间的污染也是一件让人愤怒的事情，虽然我可以设置默认为classes，但实在想不明白改的初衷是什么！]]></description>
			<content:encoded><![CDATA[<p>为什么把默认的class输出目录改成bin？这么好的名字被污染了。目录命名空间的污染也是一件让人愤怒的事情，虽然我可以设置默认为classes，但实在想不明白改的初衷是什么！</p>
]]></content:encoded>
			<wfw:commentRss>http://honnix.com/blog/archives/39/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

