<?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>诗意代码 - PoemCode &#187; Java</title>
	<atom:link href="http://www.poemcode.net/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.poemcode.net</link>
	<description>These codes, As beautiful as poetry!</description>
	<lastBuildDate>Sun, 05 Feb 2012 13:10:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>温故知新：nested class &amp; inner class</title>
		<link>http://www.poemcode.net/2010/07/nested-inner-class/</link>
		<comments>http://www.poemcode.net/2010/07/nested-inner-class/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 14:05:56 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=1424</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 62px"><img src="http://www.poemcode.net/wp-content/uploads/2010/02/java.gif" alt="" title="Java" width="52" height="88" class="size-full wp-image-1021" /></div> 

如果不是去读 Android 的源码，我不会想到在自己的 toolkit 里还有 inner class 这么一把小“锉刀”。如果不是发现<q>non-static variable this cannot be referenced from a static context</q>，我不会想到去查 inner class 的知识，也就不会发现自己对 inner class 的理解一直都是错误的。

七年前学习 Java 时，明白一个 class 可以定义在另外一个 class 里，编译后各自生一个后缀为 .class 的文件，此后很少用到这种方式，直到看到 Android ，叹其大量运用 inner class。当我试图对某个 inner class 进行修改，删去其类修饰符（class modifier）中的 static 时，Eclipse 给出了这样的提示：]]></description>
			<content:encoded><![CDATA[<blockquote><p>
<big></p>
<p style="padding-left: 60px;">温故而知新，可以为师矣。</p>
<p style="padding-left: 240px;">&#8211; 孔子 《论语》</p>
<p></big>
</p></blockquote>
<div id="attachment_1440" class="wp-caption alignright" style="width: 410px"><img src="http://www.poemcode.net/wp-content/uploads/2010/07/Inner-Class.png" alt="Inner Class" title="Inner Class" width="400" height="280" class="size-full wp-image-1440" /><p class="wp-caption-text">Inner Class? Static Nested Class?</p></div>
<p>如果不是去读 Android 的源码，我不会想到在自己的 toolkit 里还有 inner class 这么一把小“锉刀”。如果不是发现<q>non-static variable this cannot be referenced from a static context</q>，我不会想到去查 inner class 的知识，也就不会发现自己对 inner class 的理解一直都是错误的。</p>
<p>七年前学习 Java 时，明白一个 class 可以定义在另外一个 class 里，编译后各自生一个后缀为 .class 的文件，此后很少用到这种方式，直到看到 Android ，叹其大量运用 inner class。当我试图对某个 inner class 进行修改，删去其类修饰符（class modifier）中的 static 时，Eclipse 给出了这样的提示：</p>
<blockquote><p>No enclosing instance of type Hello is accessible. Must qualify the allocation with an enclosing instance of type Hello (e.g. x.new A() where x is an instance of Hello).</p></blockquote>
<p>顿时我糊涂了，明明看到诸如 <tt>EnclosingClass.InnerClass inner = new Enclosing.InnerClass()</tt> 一类的写法大行其道，怎么我写出来就出错了呢？当我按照提示，首先获得 <tt>EnclosingClass</tt> 的实例 <tt>outter</tt>，然后再<tt>EnclosingClass.InnerClass inner = outter.new InnerClass()</tt>，编译器告诉我：OK！</p>
<p>在代码编译通过并正常执行后，我对自己的 Java 知识产生了怀疑：我对 inner class 的理解是充分和正确的吗？在质疑中，我找到《The Java Language Specification》对 inner class 的定义：</p>
<blockquote><p>An inner class is a nested class that is not explicitly or implicitly declared static.</p></blockquote>
<p>虽然有了上述定义，可还是不清楚，其采用了一个新的名词 nested class 来解释，可是 nested class 又是什么呢？继续来看《The Java Language Specification》：</p>
<blockquote><p>A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class that is not a nested class.</p></blockquote>
<p>一个 class A 如果定义在了另一个 class B 或 interface B 里，那么这个 class A 就是 nested class，class B 或 interface B 则被称为 enclosing class。至于 class A 是定义在了 class  B 或 interface B 的什么地方，例如 method 和 constructor，则是没有限制的。再打开《The Java Tutorial》，找到 nested class 的<a title="Nested Classes" href="http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/java/javaOO/nested.html" target="blank">相关表述</a>：</p>
<blockquote><p>Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.</p></blockquote>
<p>恍然大悟，原来我理解中的 inner class 其实是 nested class，只有non-static 的 nested class 才能被称为 inner class，否则就是 static nested class！《The Java Tutorial》把 nested class 笼统分为两类，而更深入一点的话，inner class   还可以继续划分成三类：local class、anonymous class、non-static member class。根据《The Java Language Specification》的描述，local class 和 member class 分别定义如下：</p>
<blockquote><p>A local class is a nested class that is not a member of any class and that has a name.</p>
<p>A member class is a class whose declaration is directly enclosed in another class or interface declaration.</p></blockquote>
<p>由此看来，简单把 inner class 等同于 non-static member class 也是不正确。焦点重新回到 inner class 上，了解一下 inner class 的部分规则：</p>
<blockquote><p>Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).</p>
<p>It is a compile-time error if a local class declaration contains any one of the following access modifiers: public, protected, private, or static.</p>
<p>An anonymous class is never abstract (§8.1.1.1). &#8230; An anonymous class is always implicitly final (§8.1.1.2).</p></blockquote>
<p>inner class 不能被声明为 static，不能有 static initalizer（静态初始化块），不能是 interface（因为 member interface 一律都是 static 的），不能声明 static member，&#8211;compile-time constant field （诸如 static final int i = 0）除外。<q>an inner class is associated with an instance of its enclosing class</q> ，换句话说，没有 enclosing class 的 instance 就不会有 inner class 的 instance，我想 enclosing class 和 inner class 之间可以用 UML 中的 composition 来表示。</p>
<p>尽管语言设计者给 inner class 了这么多的限制，但是也不忘给它一些弥补，&#8211;inner class 可以访问 enclosing class 的所有 member，包括 method、field、nested class、nested interface，哪怕它是 private 也可以。<strong>但是有一个前提，inner class instance 能够访问 enclosing class instace，因为并非所有的 inner class 都能访问的到，比如在声明在 static method 中的 local class。</strong></p>
<p>相较之下，static nested class 的 instance 则是可以隔离 enclosing class 而独立存活的，但是它 <q>cannot refer directly to instance variables or methods defined in its enclosing class</q>。</p>
<p>至此，对 nested class 和 inner class 的探索告一段落，虽然前前后后翻阅了不少的资料，修正了此前的片面理解，但是绝算不上深刻理解。最后用一朋友的签名来作结：越学越知道要学。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2010/07/nested-inner-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解读《The Open Source Developer Report》</title>
		<link>http://www.poemcode.net/2010/07/open-source-developer-report/</link>
		<comments>http://www.poemcode.net/2010/07/open-source-developer-report/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 10:58:12 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Eclpse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=1337</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 88px"><img src="http://www.poemcode.net/wp-content/uploads/2010/07/eclipse-icon-225x225.png" alt="eclipse" title="eclipse" width="88" height="88" /  ></div>

每一年 Eclipse 都会在社区内部进行一项调查，来了解开发者的动态，前不久他们公布了2010年的调查报告，从中可以看到一些有趣的趋势。

先从大的方面来看，我觉得有三个亮点，首先是越来越多的开发者采用 Linux 做为自己的 OS，我想这和 Eclipse 社区成员大多是开源“粉丝”这一现状有关，Eclipse 本身是 Open Source，它的用户绝大部分不会是 .net 程序员，因此不是非要使用 Windows。以我为例，Java, PHP, Python, Ruby, C, MySQL 是我经常接触到的技术，个人环境使用 Linux 完全可以胜任，不过公司环境还是使用 Windows，--这不是我能够控制的。
]]></description>
			<content:encoded><![CDATA[<div id="attachment_1352" class="wp-caption alignleft" style="width: 310px"><img src="http://www.poemcode.net/wp-content/uploads/2010/07/OS-for-development-300x212.png" alt="OS for development" title="OS for development" width="300" height="212" class="size-medium wp-image-1352" /><p class="wp-caption-text">OS for development</p></div>
<p>每一年 Eclipse 都会在社区内部进行一项调查，来了解开发者的动态，前不久他们公布了2010年的<a title="Eclipse Community Survey 2010" href="http://www.eclipse.org/org/press-release/20100604_survey2010.php" target="_blank">调查报告</a>，从中可以看到一些有趣的趋势。</p>
<p>先从大的方面来看，我觉得有三个亮点，首先是越来越多的开发者采用 Linux 做为自己的 OS，我想这和 Eclipse 社区成员大多是开源“粉丝”这一现状有关，Eclipse 本身是 Open Source，它的用户绝大部分不会是 .net 程序员，因此不是非要使用 Windows。以我为例，Java, PHP, Python, Ruby, C, MySQL 是我经常接触到的技术，个人环境使用 Linux 完全可以胜任，不过公司环境还是使用 Windows，&#8211;这不是我能够控制的。</p>
<blockquote><p>Linux continues to gain market share on the developer desktop. Close to one third of developers (33%) now use Linux as their primary development operating system; this is up from 20% in 2007. In parallel Microsoft Windows has dropped from 74% in 2007 to 58% in 2010.</p></blockquote>
<p>其次，开源解决方案依旧赢得开发者的青睐，JQuery 和 Spring 分别是构建 RIA (Rich Internet Application) 和Server Side Application 最受欢迎的 Framework。</p>
<p>最后，云计算得到越来越多的认可和采用，已经采用和将要采用的比例接近三成。从调查结果来看，Amazon 和Google 在云计算上深得人心，但是目前在这个领域，每个公司各自为战，一个概念，不同解读，各有各云，Amazon EC2，Google App Engine，Salesforce 分别代表了目前三大观点。</p>
<blockquote><p>Deploying to a cloud infrastructure is a current option or planned option for 29.5% of the respondents. Amazon EC2, Google App Engine and a private cloud are the popular choice for those considering a cloud infrastructure.</p></blockquote>
<p>在 Java 使用情况方面，大部分人已经选择了 Java SE 1.5 或 1.6，这在 Java 7 迟迟不肯露面的情形下再正常不过。但是随后一项数据让我十分惊讶：</p>
<blockquote><p>For deployment, they typically choose the Sun Hotspot JVM (69.8%) or Open JDK (21.7%).</p></blockquote>
<p>Open JDK 的比例居然能够占到21.7%，真是出乎我的意料，我一直没有搞懂 Open JDK 和 Sun JDK 的关系，就像无法理解 Open Solaris 和 Sun Solaris 一样。</p>
<p>还有一项数据，Development Methodology，比较有幽默感，先来看有哪些选项。None, Scrum, Iterative Development, Don&#8217;t know, Agile Modeling, Extreme Programming (XP), Test Driven Development (TDD), Waterfall Feature Driven Development (FDD), Rational Unified Process (RUP), ISO 9000, Lean Development, Other。这里面的都是些热门词汇，我今天才知道还有FDD、ISO 9000和Lean Developemnt，剩下的名词里，觉得眼熟，但讲不出一二三。<q>Close to a third responded that they didn&#8217;t use methodolgy (25%) or didn&#8217;t know (7.8%)</q>，我应该是属于这三分之一。</p>
<p>在 Source code management (SCM) 方面，SVN 继续独占鳌头，CVS 老态龙钟，失去的份额被 Git 和 Mercurial 这两个分布式 SCM 工具占据。Change management system 的一二名分别是 JIRA 和 Bugzilla。Build and Release Management 的头名也依旧是 ANT。</p>
<p>最后，Applicaiton Style 的数据是我比较关注的，server-centric (26.9%)，web (26.9%)，desktop application (21%)。其中desktop 居然还有21%的比例，超出意料，至少我接触到的软件里采用 Swing/SWT 来开发的少之又少。server-centric 和 web 这两个选项，我认为是很难区分的，二者应该相互依存的关系，不知道当初是怎么定义的，因此我无法从中做出分析。</p>
<p>解读这份报告，我的目的是想知道老外们现在是怎么想的，他们在关注什么，在做什么，毕竟国内的软件理念、方法还是要落后国外至少五年左右，看看国外的现在，大概可以预测国内的未来。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2010/07/open-source-developer-report/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>小试 MD5 和 DES</title>
		<link>http://www.poemcode.net/2010/06/md5_des/</link>
		<comments>http://www.poemcode.net/2010/06/md5_des/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 10:04:01 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=1252</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 62px"><img src="http://www.poemcode.net/wp-content/uploads/2010/02/java.gif" alt="" title="Java" width="52" height="88" class="size-full wp-image-1021" /></div> 
读书那会儿，觉得密码学是个很难懂的学科，工作以后，加密和解密也基本没什么接触。不巧的是，眼下正好要有一项工作，需要对加密文件进行解密，具体的步骤如下：
<ul>
	<li>步骤1：对设备编号进行MD5加密，生成解密密钥；</li>
	<li>步骤2：对.cepub文件使用解密密钥进行DES解密，并生成文件到一个临时缓冲区。</li>
</ul>
书到用时方恨少，一番查阅 API 和 Google，期间找到两篇不错的资料 <a title="Java加密技术（一）" href="http://snowolf.javaeye.com/blog/379860" target="_blank">Java 加密技术（一）</a>和 J<a title="Java加密技术（二）" href="http://snowolf.javaeye.com/blog/380034" target="_blank">ava 加密技术（二）</a>，解了燃眉之急，顺便提一下，这两篇资料的作者也是《Java 加密和解密的艺术》一书的作者。]]></description>
			<content:encoded><![CDATA[<p>读书那会儿，觉得密码学是个很难懂的学科，工作以后，加密和解密也基本没什么接触。不巧的是，眼下正好要有一项工作，需要对加密文件进行解密，具体的步骤如下：</p>
<ul>
<li>步骤1：对设备编号进行MD5加密，生成解密密钥；</li>
<li>步骤2：对.cepub文件使用解密密钥进行DES解密，并生成文件到一个临时缓冲区。</li>
</ul>
<p>书到用时方恨少，一番查阅 API 和 Google，期间找到两篇不错的资料 <a title="Java加密技术（一）" href="http://snowolf.javaeye.com/blog/379860" target="_blank">Java 加密技术（一）</a>和 J<a title="Java加密技术（二）" href="http://snowolf.javaeye.com/blog/380034" target="_blank">ava 加密技术（二）</a>，解了燃眉之急，顺便提一下，这两篇资料的作者也是《Java 加密和解密的艺术》一书的作者。</p>
<p>以下是我实现上述两个步骤的代码片段，估计下次再遇到时难免有遗忘，干脆粘贴出来，既扩充一下版面内容，又可以日后回顾。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * 对加密文件进行解密
 * 
 * @param sourceFile 加密文件
 * @param key 密钥
 * @return 解密后文件的路径
 */</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> getDecryptedFile<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> sourceFile, <span style="color: #003399;">Key</span> key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> foldPath <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/home/poemcode/&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">int</span> beginIndex <span style="color: #339933;">=</span> sourceFile.<span style="color: #006633;">lastIndexOf</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">File</span>.<span style="color: #006633;">separator</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">int</span> endIndex <span style="color: #339933;">=</span> sourceFile.<span style="color: #006633;">lastIndexOf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">String</span> dest <span style="color: #339933;">=</span> foldPath <span style="color: #339933;">+</span> sourceFile.<span style="color: #006633;">substring</span><span style="color: #009900;">&#40;</span>beginIndex, endIndex<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;.epub&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    Cipher cipher <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
        cipher <span style="color: #339933;">=</span> Cipher.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;DES&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        cipher.<span style="color: #006633;">init</span><span style="color: #009900;">&#40;</span>Cipher.<span style="color: #006633;">DECRYPT_MODE</span>, key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">NoSuchAlgorithmException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>NoSuchPaddingException e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InvalidKeyException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #003399;">InputStream</span> is <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">OutputStream</span> out <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    CipherOutputStream cos <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
        is <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">FileInputStream</span><span style="color: #009900;">&#40;</span>sourceFile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        out <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">FileOutputStream</span><span style="color: #009900;">&#40;</span>dest<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        cos <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CipherOutputStream<span style="color: #009900;">&#40;</span>out, cipher<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> buffer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">int</span> r<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>r <span style="color: #339933;">=</span> is.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>buffer<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            cos.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>buffer, <span style="color: #cc66cc;">0</span>, r<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">finally</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cos <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
                cos.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cos <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
                out.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cos <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
                is.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">return</span> dest<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * 返回DES解码的密钥
 * 
 * @param serialNumber
 *            机器序列号
 * @return 密钥
 */</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Key</span> getKey<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> serialNumber<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">Key</span> secretKey <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">MessageDigest</span> md5 <span style="color: #339933;">=</span> <span style="color: #003399;">MessageDigest</span>.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;MD5&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        md5.<span style="color: #006633;">update</span><span style="color: #009900;">&#40;</span>serialNumber.<span style="color: #006633;">getBytes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        DESKeySpec dks <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DESKeySpec<span style="color: #009900;">&#40;</span>md5.<span style="color: #006633;">digest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        SecretKeyFactory keyFactory <span style="color: #339933;">=</span> SecretKeyFactory.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;DES&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        secretKey <span style="color: #339933;">=</span> keyFactory.<span style="color: #006633;">generateSecret</span><span style="color: #009900;">&#40;</span>dks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InvalidKeyException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">NoSuchAlgorithmException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InvalidKeySpecException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">return</span> secretKey<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2010/06/md5_des/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>认知 Java Class Loading</title>
		<link>http://www.poemcode.net/2010/03/java-class-loading/</link>
		<comments>http://www.poemcode.net/2010/03/java-class-loading/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 06:48:33 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=1120</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 62px"><img src="http://www.poemcode.net/wp-content/uploads/2010/02/java.gif" alt="" title="Java" width="52" height="88" class="size-full wp-image-1021" /></div> 
对 Java Class Loading 的认知，从OOP (Object Oriented Programming) 界的一句谚语开始，那就是：Everything is Object。以现实举例，张三是对象(object)，李四也是对象(object)，对这些个体加以抽象，形成了类(class)的概念。这类和对象的区别在于，前者是抽象的概念，不论是时间，还是空间均不存在这么一个东西；后者是具体的物件，可摸得着、看得见。

在 Java 中使用关键字 class 来定义一个类，经过编译之后，便会生成一个后缀为 .class 的文件。在 Java 程序运行时，JVM 需要载入这些 .class 文件到内存中，已构造成对应的 类(class)。而这载入的过程正是由 java.lang.ClassLoader 的实例来完成，根据 JVM 的策略，不同的类(class)被组织进不同的 jar 文件，进而按照重要级别划分成不同的等级，由不同的 class loader 来负责载入。]]></description>
			<content:encoded><![CDATA[<div id="attachment_1126" class="wp-caption alignright" style="width: 336px"><img class="size-full wp-image-1126" title="Class Loader" src="http://www.poemcode.net/wp-content/uploads/2010/03/Class-Loader.png" alt="Class Loader" width="326" height="304" /><p class="wp-caption-text">Class Loader</p></div>
<p><em>此前一次面试中，曾说起有关 ClassLoader 的话题。期间对方侃侃而谈，自己虽挖空心思，也不堪他的旁敲侧击，说不出个所以然来，只怪自己道行不够，丢人现眼，也遂下决心补上这块短板，恰逢近日稍有空暇，于是查资料，翻文档，希望就此实现这一愿望。</em></p>
<p>对 Java Class Loading 的认知，从OOP (Object Oriented Programming) 界的一句谚语开始，那就是：Everything is Object。以现实举例，张三是对象(object)，李四也是对象(object)，对这些个体加以抽象，形成了类(class)的概念。这类和对象的区别在于，前者是抽象的概念，不论是时间，还是空间均不存在这么一个东西；后者是具体的物件，可摸得着、看得见。</p>
<p>在 Java 中使用关键字 class 来定义一个类，经过编译之后，便会生成一个后缀为 .class 的文件。在 Java 程序运行时，JVM 需要载入这些 .class 文件到内存中，已构造成对应的 类(class)。而这载入的过程正是由 java.lang.ClassLoader 的实例来完成，根据 JVM 的策略，不同的类(class)被组织进不同的 jar 文件，进而按照重要级别划分成不同的等级，由不同的 class loader 来负责载入，如图所示。</p>
<p>假定 MyMainClass 是某个程序的主类，当执行 java MyMainClass 时，系统就会启动下一个新的 JVM。此时 bootstrap class loader 会立即载入核心的 Java 类(class)，例如 在 rt.jar 中的 runtime 类(class) 和 i18n.jar 中的 internationalization 类(class)。</p>
<p>接下来，extension class loader 会接过接力棒，负责载入 extension library，具体的讲，就是由 ExtClassLoader 载入所有在 java.ext.dirs 路径（通常为 lib/ext）上的 jar 文件。</p>
<p>第三步，也是在开发人员看来最为关键的一步，application class loader 载入 java.class.path 路径（默认为当前路径，也可以通过 -classpath 或 -cp，或者设置CLASSPATH 进行修改）上的 jar 文件。</p>
<p>了解了上述流程之后，再来看Java Platform API Specification 对 java.lang.ClassLoader 类的描述，从中可以知道 ClassLoader 使用代理模型来搜索类和资源，并且每一个实例都会有一个与之关联的、“父”的 class loader。当 ClassLoader 实例被要求查找类或资源时，其就会让其父的 class loader 代为执行，如果执行无果，再由自己来执行。</p>
<p>以下代码是从 java.lang.ClassLoader 的片段，其中第8和11行是自行加入的注释，其余为官方源码，上述说法即由此得以印证。</p>

<div class="wp_syntax"><table><tr><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
27
28
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">synchronized</span> <span style="color: #000000; font-weight: bold;">Class</span> loadClass<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name, <span style="color: #000066; font-weight: bold;">boolean</span> resolve<span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassNotFoundException</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// First, check if the class has already been loaded</span>
    <span style="color: #000000; font-weight: bold;">Class</span> c <span style="color: #339933;">=</span> findLoadedClass<span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>parent <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// delegate to its parent class loader</span>
                c <span style="color: #339933;">=</span> parent.<span style="color: #006633;">loadClass</span><span style="color: #009900;">&#40;</span>name, <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// no parent class loader, so delegate to bootstrap class loader</span>
                c <span style="color: #339933;">=</span> findBootstrapClassOrNull<span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">ClassNotFoundException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// ClassNotFoundException thrown if class not found</span>
            <span style="color: #666666; font-style: italic;">// from the non-null parent class loader</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// If still not found, then invoke findClass in order</span>
            <span style="color: #666666; font-style: italic;">// to find the class.</span>
            c <span style="color: #339933;">=</span> findClass<span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>resolve<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        resolveClass<span style="color: #009900;">&#40;</span>c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> c<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>以下为写作过程中所参考的文档资料：</p>
<ol>
<li><a href="http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html?page=1" target="_blank">The basics of Java class loaders</a></li>
<li><a href="http://onjava.com/pub/a/onjava/2005/01/26/classloading.html?page=1" target="_blank">Internals of Java Class Loading</a></li>
<li><a href="http://java.sun.com/docs/books/tutorial/ext/basics/load.html" target="_blank">Understanding Extension Class Loading</a></li>
<li><a href="http://www.javaeye.com/topic/136427" target="_blank">重温java之classloader体系结构（含hotswap）</a></li>
<li><a href="http://www.cnblogs.com/ChrisWang/category/211171.html" target="_blank">深入JVM</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2010/03/java-class-loading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static Import 和 Constant Interface Antipattern</title>
		<link>http://www.poemcode.net/2010/02/static-import-constant-interface-antipattern/</link>
		<comments>http://www.poemcode.net/2010/02/static-import-constant-interface-antipattern/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:36:06 +0000</pubDate>
		<dc:creator>Xu Haojie</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.poemcode.net/?p=1016</guid>
		<description><![CDATA[<div class="wp-caption alignright" style="width: 62px"><img src="http://www.poemcode.net/wp-content/uploads/2010/02/java.gif" alt="" title="Java" width="52" height="88" class="size-full wp-image-1021" /></div> 

某日，一同事向我询问 Java 5 中为何要引入 Static Import，一时答不上来，自责平日里“学而不思”，Java 5 的发布已经是六年前（2004年9月30日）的事情了，到现在也只是“知其然”，而不“知其所以然”，之后遂决定对这一问题做一番探究。

此番探究从 SUN 的官方解释入手，从 <a title="Static Import" href="http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html" target="_blank">Static Import</a> 一文中，可以明白引入的目的在于解决 Constant Interface Antipattern。那么什么是 Constant Interface Antiparttern ? 这要从访问 static member 开始说起，如下面代码所示，在 member 之前需要有其对应的类名。]]></description>
			<content:encoded><![CDATA[<div id="attachment_1021" class="wp-caption alignright" style="width: 62px"><img src="http://www.poemcode.net/wp-content/uploads/2010/02/java.gif" alt="" title="Java" width="52" height="88" class="size-full wp-image-1021" /><p class="wp-caption-text">Java</p></div>
<p>某日，一同事向我询问 Java 5 中为何要引入 Static Import，一时答不上来，自责平日里“学而不思”，Java 5 的发布已经是六年前（2004年9月30日）的事情了，到现在也只是“知其然”，而不“知其所以然”，之后遂决定对这一问题做一番探究。</p>
<p>此番探究从 SUN 的官方解释入手，从 <a title="Static Import" href="http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html" target="_blank">Static Import</a> 一文中，可以明白引入的目的在于解决 Constant Interface Antipattern。那么什么是 Constant Interface Antiparttern ? 这要从访问 static member 开始说起，如下面代码所示，在 member 之前需要有其对应的类名。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000066; font-weight: bold;">double</span> r <span style="color: #339933;">=</span> <span style="color: #003399;">Math</span>.<span style="color: #006633;">cos</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Math</span>.<span style="color: #006633;">PI</span> <span style="color: #339933;">*</span> theta<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>这样的用法本是合情合理，但是“懒惰”的程序员抱怨其太繁琐了：我要直接访问常量，无需加以类名！于是就生出一个法子：把 static member 放到 interface 里，然后 inherit 这个 interface。&#8211;这种做法就是 Constant Interface Antiparttern，这一术语可以追溯到 Joshua Bloch 所著的《Effictive Java》，关于这一问题的详细描述，可以参考原作（P98, Item 19: Use interface only to define types），当然，也可以从 Google books 里找到，请看<a title="Effictive Java" href="http://books.google.com/books?id=ka2VUBqHiWkC&amp;pg=PA98&amp;lpg=PA98&amp;dq=Constant+Interface+Antipattern&amp;source=bl&amp;ots=yXIkLhw3P2&amp;sig=KIz7vHSe5u14SHs9qqxZGHWGoow&amp;hl=en&amp;ei=9YxrS6KXNM6HkAWw66j4Aw&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=9&amp;ved=0CB8Q6AEwCA#v=onepage&amp;q=Constant%20Interface%20Antipattern&amp;f=false" target="_blank">这里</a>。</p>
<p>在原作当中，Joshua Bloch 是这样描述 constant interface：</p>
<blockquote><p>Such an interface contains no methods; it consists solely of static final fields, each exporting a constant. Classes using these constants implement the interface to avoid the need to qualify constant names with a class name.</p></blockquote>
<p>尽管这种做法时常出现，甚至在 Java SE API 当中也能找到，例如 java.io.ObjectStreamConstants，但是这种做法却是不值得提倡的，Joshua Bloch 归纳了三点原因：</p>
<blockquote><p>That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail leak into the class&#8217;s exported API.</p>
<p>If in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility</p>
<p>If a nonfinal class implements  a constant interface, all of its subclasses will have their namespace polluted by the constants in the interface</p></blockquote>
<p>与此类似，从 Wikipedia 上查看 <a title="Constant Interface" href="http://en.wikipedia.org/wiki/Constant_interface" target="_blank">Constant Interface</a> 的词条，可以看到相差无几的解释，也可以看到详细的代码示例，也就省去在这里展示代码的必要了。</p>
<p>可以说 Static Import 正是为了解决 Constant Interface Antipattern 而生，但是在使用的时候，却要慎之又慎。如果过度使用，则会导致 namespace 被“污染”，代码难以阅读和维护。试想有 N 个 static import， 你将如何区分 哪个 static member 来自哪个 class？也千万不要使用“*”，把 class 的全部 static member 一股脑给 static import。如果你只是想使用一两个 member，那就分别 static import 吧。</p>
<p>最后以 Static Import 一文的结束语来结束这篇博文：</p>
<blockquote><p>Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.poemcode.net/2010/02/static-import-constant-interface-antipattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

