﻿<?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>Gavin&#039;s Blog &#187; Java</title>
	<atom:link href="http://laigw.name/cat/tech/java/feed" rel="self" type="application/rss+xml" />
	<link>http://laigw.name</link>
	<description>Keep it simple, stupid. Simplicity is beauty.</description>
	<lastBuildDate>Sun, 29 Jan 2012 07:14:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Java反射经典实例 Java Reflection Cookbook</title>
		<link>http://laigw.name/post/235.html</link>
		<comments>http://laigw.name/post/235.html#comments</comments>
		<pubDate>Wed, 19 Nov 2008 06:31:18 +0000</pubDate>
		<dc:creator>Gavin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Java反射]]></category>
		<category><![CDATA[Reflection]]></category>

		<guid isPermaLink="false">http://www.laigw.name/?p=235</guid>
		<description><![CDATA[    Java提供了一套机制来动态执行方法和构造方法，以及数组操作等，这套机制就叫——反射。反射机制是如今很多流行框架的实现基础，其中包括Spring、Hibernate等。原理性的问题不是本文的重点，接下来让我们在实例中学习这套精彩的机制。

1. 得到某个对象的属性

&#160;查看代码 JAVA1
2
3
4
5
6
7
8
9
public Object getProperty&#40;Object owner, String fieldName&#41; throws Exception &#123;
    Class ownerClass = owner.getClass&#40;&#41;;
&#160;
    Field field = ownerClass.getField&#40;fieldName&#41;;
&#160;
    Object property = field.get&#40;owner&#41;;
&#160;
    return property;
&#125;

Class ownerClass = owner.getClass()：得到该对象的Class。
Field field = ownerClass.getField(fieldName)：通过Class得到类声明的属性。
Object property = field.get(owner)：通过对象得到该属性的实例，如果这个属性是非公有的，这里会报IllegalAccessException。
2. 得到某个类的静态属性

&#160;查看代码 JAVA1
2
3
4
5
6
7
8
9
10
public Object getStaticProperty&#40;String className, [...]]]></description>
		<wfw:commentRss>http://laigw.name/post/235.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>POI的HSSF操作Excel用法小结</title>
		<link>http://laigw.name/post/29.html</link>
		<comments>http://laigw.name/post/29.html#comments</comments>
		<pubDate>Fri, 14 Nov 2008 12:29:11 +0000</pubDate>
		<dc:creator>Gavin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[HSSF]]></category>
		<category><![CDATA[POI]]></category>

		<guid isPermaLink="false">http://www.laigw.name/?p=29</guid>
		<description><![CDATA[近日出于工作需要，总结了一下POI的HSSF操作Excel的用法，将之封装成一个类，便于以后重复使用。

封装主类：

&#160;查看代码 JAVA1
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
package name.laigw.utils.excel;
&#160;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
&#160;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
&#160;
/**
* Handle excel(read and write) class by POI
*
* @author Gavin
*/
public class ExcelHandleByPOI &#123;
&#160;
public static void main&#40;String&#91;&#93; args&#41; &#123;
&#160;
String filePath = &#34;input/test_from.xls&#34;;
String filePathTo = &#34;input/test_to.xls&#34;;
&#160;
List listList = ExcelHandleByPOI.readFromExcel&#40;filePath, true&#41;;
System.out.println&#40;&#34;Data write to: &#34; + ExcelHandleByPOI.writeToExcel&#40;listList, filePathTo&#41;&#41;;
&#160;
//~ display the table content for demo
Iterator [...]]]></description>
		<wfw:commentRss>http://laigw.name/post/29.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一篇关于Java中文乱码问题阐述较详细的文章</title>
		<link>http://laigw.name/post/25.html</link>
		<comments>http://laigw.name/post/25.html#comments</comments>
		<pubDate>Fri, 14 Nov 2008 12:27:01 +0000</pubDate>
		<dc:creator>Gavin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[中文乱码]]></category>

		<guid isPermaLink="false">http://www.laigw.name/?p=25</guid>
		<description><![CDATA[由于Java编程中的中文问题是一个老生常谈的问题，在阅读了许多关于Java中文问题解决方法之后，结合作者的编程实践，我发现过去谈的许多方法都不能清晰地说明问题及解决问题，尤其是跨平台时的中文问题。
于是我给出此篇文章，内容包括对控制台运行的class、Servelets、JSP及EJB类中的中文问题我剖析和建议解决办法。希望大家指教。

Abstract：本文深入分析了Java程序设计中Java编译器对Java源文件和JVM对class类文件的编码/解码过程，通过此过程的解析透视出了Java编程中中文问题产生的根本原因，最后给出了建议的最优化的解决Java中文问题的方法。
1、中文问题的来源
计算机最初的操作系统支持的编码是单字节的字符编码，于是，在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理。
随着计算机的发展，为了适应世界其它民族的语言（当然包括我们的汉字），人们提出了UNICODE编码，它采用双字节编码，兼容英文字符和其它民族的双字节字符编码，所以，目前，大多数国际性的软件内部均采用UNICODE编码，在软件运行时，它获得本地支持系统（多数时间是操作系统）默认支持的编码格式，然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。
Java的JDK和JVM即是如此，我这里说的JDK是指国际版的JDK，我们大多数程序员使用的是国际化的JDK版本，以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节编码语言，为了能让计算机处理中文，我们自己制定的gb2312、GBK、GBK2K等标准以适应计算机处理的需求。
所以，大部分的操作系统为了适应我们处理中文的需求，均定制有中文操作系统，它们采用的是GBK,GB2312编码格式以正确显示我们的汉字。如：中文Windows默认采用的是GBK编码显示，在中文Windows2000中保存文件时默认采用的保存文件的编码格式也是GBK的，即所有在中文Windows2000中保存的文件它的内部编码默认均采用GBK编码，注意：GBK是在GB2312基础上扩充来的。
由于Java语言内部采用UNICODE编码，所以在Java程序运行时，就存在着一个从UNICODE编码和对应的操作系统及浏览器支持的编码格式转换输入、输出的问题，这个转换过程有着一系列的步骤，如果其中任何一步出错，则显示出来的汉字就会出是乱码，这就是我们常见的Java中文问题。
同时，Java是一个跨平台的编程语言，也即我们编写的程序不仅能在中文windows上运行，也能在中文Linux等系统上运行，同时也要求能在英文等系统上运行（我们经常看到有人把在中文Windows2000上编写的Java程序，移植到英文Linux上运行）。这种移植操作也会带来中文问题。
还有，有人使用英文的操作系统和英文的IE等浏览器，来运行带中文字符的程序和浏览中文网页，它们本身就不支持中文，也会带来中文问题。
几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递，而不是按中文编码传递，所以，传递中文参数时也会有问题，从而带来乱码现象。
总之，以上几个方面是Java中的中文问题的主要来源，我们把以上原因造成的程序不能正确运行而产生的问题称作：Java中文问题。
2、Java编码转换的详细过程
我们常见的Java程序包括以下类别：
*直接在console上运行的类(包括可视化界面的类)
*JSP代码类（注：JSP是Servlets类的变型）
*Servelets类
*EJB类
*其它不可以直接运行的支持类
这些类文件中，都有可能含有中文字符串，并且我们常用前三类Java程序和用户直接交互，用于输出和输入字符，如：我们在JSP和Servlet中得到客户端送来的字符，这些字符也包括中文字符。无论这些Java类的作用如何，这些Java程序的生命周期都是这样的：
*编程人员在一定的操作系统上选择一个合适的编辑软件来实现源程序代码并以.Java扩展名保存在操作系统中，例如我们在中文Windows2000中用记事本编辑一个Java源程序。
*编程人员用JDK中的Javac.exe来编译这些源代码，形成.class类(JSP文件是由容器调用JDK来编译的)。
*直接运行这些类或将这些类布署到WEB容器中去运行，并输出结果。
那么，在这些过程中，JDK和JVM是如何将这些文件如何编码和解码并运行的呢？
这里，我们以中文Windows2000操作系统为例说明Java类是如何来编码和被解码的。
第一步，我们在中文Windows2000中用编辑软件如记事本编写一个Java源程序文件(包括以上五类Java程序)，程序文件在保存时默认采用了操作系统默认支持GBK编码格式(操作系统默认支持的格式为file.encoding格式)形成了一个.Java文件，也即，Java程序在被编译前，我们的Java源程序文件是采用操作系统默认支持的file.encoding编码格式保存的，Java源程序中含有中文信息字符和英文程序代码；要查看系统的file.encoding参数，可以用以下代码：

&#160;查看代码 JAVA1
2
3
4
5
6
7
8
9
public class ShowSystemDefaultEncoding
&#123;
public static void  main&#40;String&#91;&#93; args&#41;
&#123;
String encoding  =
System.getProperty&#40;”file.encoding”&#41;;
System.out.println&#40;encoding&#41;;
&#125;
&#125;

第二步，我们用JDK的Javac.exe文件编译我们的Java源程序，由于JDK是国际版的，在编译的时候，如果我们没有用-encoding参数指定我们的Java源程序的编码格式，则Javac.exe首先获得我们操作系统默认采用的编码格式，也即在编译Java程序时，若我们不指定源程序文件的编码格式，JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式，如Windows2000，它的值为GBK)，然后JDK就把我们的Java源程序从file.encoding编码格式转化为Java内部默认的UNICODE格式放入内存中。
然后，Javac把转换后的unicode格式的文件进行编译成.class类文件，此时.class文件是UNICODE编码的，它暂放在内存中，紧接着，JDK将此以UNICODE编码的编译后的class文件保存到我们的操作系统中形成我们见到的.class文件。
对我们来说，我们最终获得的.class文件是内容以UNICODE编码格式保存的类文件，它内部包含我们源程序中的中文字符串，只不过此时它己经由file.encoding格式转化为UNICODE格式了。
这一步中，对于JSP源程序文件是不同的，对于JSP，这个过程是这样的：即WEB容器调用JSP编译器，JSP编译器先查看JSP文件中是否设置有文件编码格式，如果JSP文件中没有设置JSP文件的编码格式，则JSP编译器调用JDK先把JSP文件用JVM默认的字符编码格式(也即WEB容器所在的操作系统的默认的file.encoding)转化为临时的Servlet类，然后再把它编译成UNICODE格式的class类，并保存在临时文件夹中。
如：在中文Windows2000上，WEB容器就把JSP文件从GBK编码格式转化为UNICODE格式，然后编译成临时保存的Servlet类，以响应用户的请求。
第三步，运行第二步编译出来的类，分为三种情况：
A、 直接在console上运行的类
B、 EJB类和不可以直接运行的支持类(如JavaBean类)
C、 JSP代码和Servlet类
D、 Java程序和数据库之间
下面我们分这四种情况来看。
A、直接在console上运行的类
这种情况，运行该类首先需要JVM支持，即操作系统中必须安装有JRE。运行过程是这样的：首先Java启动JVM，此时JVM读出操作系统中保存的class文件并把内容读入内存中，此时内存中为UNICODE格式的class类，然后JVM运行它，如果此时此类需要接收用户输入，则类会默认用file.encoding编码格式对用户输入的串进行编码并转化为unicode保存入内存（用户可以设置输入流的编码格式）。
程序运行后，产生的字符串（UNICODE编码的）再回交给JVM，最后JRE把此字符串再转化为file.encoding格式(用户可以设置输出流的编码格式)传递给操作系统显示接口并输出到界面上。以上每一步的转化都需要正确的编码格式转化，才能最终不出现乱码现象。 B、EJB类和不可以直接运行的支持类(如JavaBean类)
由于EJB类和不可以直接运行的支持类，它们一般不与用户直接交互输入和输出，它们常常与其它的类进行交互输入和输出，所以它们在第二步被编译后，就形成了内容是UNICODE编码的类保存在操作系统中了，以后只要它与其它的类之间的交互在参数传递过程中没有丢失，则它就会正确的运行。
C、JSP代码和Servlet类
经过第二步后，JSP文件也被转化为Servlets类文件，只不过它不像标准的Servlets一校存在于classes目录中，它存在于WEB容器的临时目录中，故这一步中我们也把它做为Servlets来看。
对于Servlets，客户端请求它时，WEB容器调用它的JVM来运行Servlet，首先，JVM把Servlet的class类从系统中读出并装入内存中，内存中是以UNICODE编码的Servlet类的代码，然后JVM在内存中运行该Servlet类，如果Servlet在运行的过程中，需要接受从客户端传来的字符如：表单输入的值和URL中传入的值，此时如果程序中没有设定接受参数时采用的编码格式，则WEB容器会默认采用ISO-8859-1编码格式来接受传入的值并在JVM中转化为UNICODE格式的保存在WEB容器的内存中。
Servlet运行后生成输出，输出的字符串是UNICODE格式的，紧接着，容器将Servlet运行产生的UNICODE格式的串（如html语法，用户输出的串等）直接发送到客户端浏览器上并输出给用户，如果此时指定了发送时输出的编码格式，则按指定的编码格式输出到浏览器上，如果没有指定，则默认按ISO-8859-1编码发送到客户的浏览器上。
D、Java程序和数据库之间
对于几乎所有数据库的JDBC驱动程序，默认的在Java程序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的，所以，我们的程序在向数据库内存储包含中文的数据时，JDBC首先是把程序内部的UNICODE编码格式的数据转化为ISO-8859-1的格式，然后传递到数据库中，在数据库保存数据时，它默认即以ISO-8859-1保存，所以，这是为什么我们常常在数据库中读出的中文数据是乱码。
3、分析常见的Java中文问题几个必须清楚的原则
首先，经过上面的详细分析，我们可以清晰地看到，任何Java程序的生命期中，其编码转换的关键过程是在于：最初编译成class文件的转码和最终向用户输出的转码过程。
其次，我们必须了解Java在编译时支持的、常用的编码格式有以下几种：
*ISO-8859-1，8-bit, 同8859_1,ISO-8859-1,ISO_8859_1等编码
*Cp1252，美国英语编码，同ANSI标准编码
*UTF-8，同unicode编码
*GB2312，同gb2312-80,gb2312-1980等编码
*GBK，同MS936，它是gb2312的扩充及其它的编码，如韩文、日文、繁体中文等。同时，我们要注意这些编码间的兼容关体系如下：
unicode和UTF-8编码是一一对应的关系。GB2312可以认为是GBK的子集，即GBK编码是在gb2312上扩展来的。同时，GBK编码包含了20902个汉字，编码范围为：0×8140-0xfefe，所有的字符可以一一对应到UNICODE2.0中来。
再次，对于放在操作系统中的.Java源程序文件，在编译时，我们可以指定它内容的编码格式，具体来说用-encoding来指定。注意：如果源程序中含有中文字符，而你用-encoding指定为其它的编码字符，显然是要出错的。
用-encoding指定源文件的编码方式为GBK或gb2312，无论我们在什么系统上编译含有中文字符的Java源程序都不会有问题，它都会正确地将中文转化为UNICODE存储在class文件中。
然后，我们必须清楚，几乎所有的WEB容器在其内部默认的字符编码格式都是以ISO-8859-1为默认值的，同时，几乎所有的浏览器在传递参数时都是默认以UTF-8的方式来传递参数的。
所以，虽然我们的Java源文件在出入口的地方指定了正确的编码方式，但其在容器内部运行时还是以ISO-8859-1来处理的。
4、中文问题的分类及其建议最优解决办法
了解以上Java处理文件的原理之后，我们就可以提出了一套建议最优的解决汉字问题的办法。我们的目标是：我们在中文系统中编辑的含有中文字符串或进行中文处理的Java源程序经编译后可以移值到任何其它的操作系统中正确运行，或拿到其它操作系统中编译后能正确运行，能正确地传递中文和英文参数，能正确地和数据库交流中英文字符串。我们的具体思路是：在Java程序转码的入口和出口及Java程序同用户有输入输出转换的地方限制编码方法使之正确即可。
具体解决办法如下：
1、 针对直接在console上运行的类
对于这种情况，我们建议在程序编写时，如果需要从用户端接收用户的可能含有中文的输入或含有中文的输出，程序中应该采用字符流来处理输入和输出，具体来说，应用以下面向字符型节点流类型：
对文件：FileReader，FileWrieter
其字节型节点流类型为：FileInputStream，FileOutputStream
对内存（数组）：CharArrayReader，CharArrayWriter
其字节型节点流类型为：ByteArrayInputStream，ByteArrayOutputStream
对内存（字符串）：StringReader，StringWriter
对管道：PipedReader，PipedWriter
其字节型节点流类型为：PipedInputStream，PipedOutputStream
同时，应该用以下面向字符型处理流来处理输入和输出：
BufferedWriter，BufferedReader
其字节型的处理流为：BufferedInputeStream，BufferedOutputStream
InputStreamReader，OutputStreamWriter
其字节型的处理流为：DataInputStream，DataOutputStream
其中InputStreamReader和InputStreamWriter用于将字节流按照指定的字符编码集转换到字符流，如：
InputStreamReader in = new InputStreamReader(System.in，”GB2312″)；
OutputStreamWriter out = new OutputStreamWriter (System.out，”GB2312″)；
例如：采用如下的示例Java编码就达到了要求：

&#160;查看代码 JAVA1
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
//Read.Java
import Java.io.*;
public class Read
&#123;
public static  void main&#40;String&#91;&#93; args&#41;
throws IOException
&#123;
String str  =
“\n中文测试，这是内部硬编码的串
“+”\ntest english character”;
String strin=  “”;
BufferedReader stdin =
new  BufferedReader&#40;new
InputStreamReader&#40;System.in,”gb2312″&#41;&#41;;
//设置输入接口按中文编码
BufferedWriter  stdout =
new  BufferedWriter&#40;new
OutputStreamWriter&#40;System.out,”gb2312″&#41;&#41;;
//设置输出接口按中文编码
stdout.write&#40;”请输入:”&#41;;
stdout.flush&#40;&#41;;
strin [...]]]></description>
		<wfw:commentRss>http://laigw.name/post/25.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>彻底理解面向对象的多态</title>
		<link>http://laigw.name/post/22.html</link>
		<comments>http://laigw.name/post/22.html#comments</comments>
		<pubDate>Fri, 14 Nov 2008 12:22:14 +0000</pubDate>
		<dc:creator>Gavin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.laigw.name/?p=22</guid>
		<description><![CDATA[彻底理解面向对象的多态
一、序言
初学C++的时候，对面向对象的多态实现机制总处于模糊的理解状态。近日研究起java，才得以对其有较清晰的认识。现将我对多态的认识写成日志，以供己供人参考。

二、知识准备
在分析多态之前，有必要对一些概念巩固认识一下。
1、变量
变量是一个由标识符命名的数据项。它包括三个属性：类型、名称、值。此外，变量还具有一个作用范围。
2、区分声明和定义
对象（包括基本类型对象和引用对象）的声明和定义：
对象的声明：描述对象名称和确切类型，用于指代其他地方定义的对象。一个对象可以有多个声明；
对象的定义：确定对象的类型并分配内存，用于创建新的对象。一个对象只能有一个定义。
简言之，声明重于“描述”，定义在于“确定”，即声明仅仅向编译器描述了一个变量的内存结构，但符合该内存结构的内存区域则不一定存在，而定义则生成了一块符合该内存结构的实际内存区域。这种做法类似于接口与实现分离的思想。
3、理解Method-call(方法调用)绑定方式
1)所谓“绑定(binding)”，就是建立method  call和method body(方法本体)的关联。
2)先期绑定(early binding)，又称静态绑定(static  binding)，指绑定动作发生于程序执行前(由编译器和连接器完成)。
3)后期绑定(late binding)，又称动态绑定(static  binding)，或执行期绑定(run-time  binding)，指绑定动作将在执行期间才根据对象型别而进行(由JVM实现)。
程序语言的后期绑定机制作法因语言的不同而不同，但必得有某种“型别信息”被置于对象内。
4、动态绑定工作流程如下：
假定对象o是类C1,C2,C3,&#8230;和Cn的实例，C2是C1的子类，C3是C2的子类，&#8230;，Cn是Cn-1的子类。也就是说，C1是最通用的类，Cn是最具体的类。在java中，C1是Object类。如果o调用方法p，JVM在Cn,Cn-1,Cn-2,&#8230;C2,C1中查找方法p的实现。按照这种顺序直到找到为止。一旦找到这个实现，查找将停止并且调用第一个找到的实现。
5、对象引用和对象的区别
对象引用类似一个指针的作用，它是操作对象的变量；
对象是有new关键字创建而得到的实体。
6、对象知道自己将要如何做
调用某个被覆盖的方法（直接覆盖）或某个使用覆盖方法的方法（间接覆盖）时，该方法的动作是对象创建(使用new)所使用类中定义的动作。这个动作并不是由指代该对象的引用类型所决定的。任何祖先类的变量都能存放某个后代类的对象，但该对象总是记得各个方法应使用哪种方法动作（哪怕使用强制类型转换！）。引用变量的类型不起作用。起作用的是创建对象时的类名。
7、引用变量决定了能使用的方法，而对象决定了将使用方法的哪个定义
new使用某个类名而创建了对象，但该对象却存储至某个祖先类的变量中；变量决定了该变量能使用什么方法，但对象创建所使用的类都决定了将使用方法的哪个定义。
此外，这一规则的特例是：形参决定对象调用哪一种方法，而实参决定对象调用方法的哪一种定义。
]]></description>
		<wfw:commentRss>http://laigw.name/post/22.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>学习在java中计算基本的时间段</title>
		<link>http://laigw.name/post/19.html</link>
		<comments>http://laigw.name/post/19.html#comments</comments>
		<pubDate>Fri, 14 Nov 2008 12:18:25 +0000</pubDate>
		<dc:creator>Gavin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[时间]]></category>
		<category><![CDATA[时间段]]></category>

		<guid isPermaLink="false">http://www.laigw.name/?p=19</guid>
		<description><![CDATA[学习在java中计算基本的时间段
概述
如果你知道怎样在java中使用日期，那么使用时间和它才不多一样简单。这篇文章告诉你怎样把他们的差别联系起来。Robert Nielsen还告诉你怎样使用java来计算抵达航班和制造过程的时间。
作者：Robert Nielsen
翻译：Cocia Lin
这篇文章是在我发表过的&#60;计算Java时间&#62;(译者:已经翻译完成)的基础上的。在这里，我列出那篇文章几个你应该熟悉得关键点。如果这几点你不太清楚，我建议你读一下&#60;计算Java时间&#62;，了解一下。
1. Java计算时间依靠1970年1月1日开始的毫秒数.
2. Date类的构造函数Date()返回代表当前创建的时刻的对象。Date的方法getTime()返回一个long值在数值上等于1970年1月1日之前或之后的时刻。
3. DateFormat类用来转换Date到String,反之亦然。静态方法getDateInstance()返回DateFormat的缺省格式；getDateInstance(DateFormat.FIELD)返回指定的DateFormat对象格式。Format(Date d)方法返回String表示日期，例如＂January 1,2002.＂反过来，parse(String s)方法返回以参数字符串表示的Date对象。
4. format()方法返回的字符串格式根据不同地区的时间设置而有所不同。
5. GregorianCalendear类有两个重要的构造函数：GregorianCalerdar(),返回代表当前创建时间的对象；GregorianCalendar(int year,int month,int date)返回代表任意日期的对象。GregorianCalendar类的getTime()方法返回日期对象。Add(int field,int amount)方法通过加或减时间单位，象天数，月数或年数来计算日期。
GregorianCalendar和 时间
两个GregorianCalendar的构造函数可以用来处理时间。前者创建一个表示日期，小时和分钟的对象：
GregorianCalendar(int year, int month, int date, int hour, int minute)
第二个创建一个表示一个日期，小时，分钟和秒：
GregorianCalendar(int year, int month, int date, int hour, int minute, int second)

首先，我应该提醒一下，每一个构造函数需要时间信息中的日期信息(年，月，日)。如果你想说2:30 p.m.,你必须指出日期。
同样，每一个GregorianCalendar构造函数创建一个在时间上使用毫秒计算的对象。所以，如果你的构造函数只提供年，月，日参数，那小时，分钟，秒和毫秒的值将被置0.
DateFormat和时间
你可以使用静态方法getDateTimeInstance(int dateStyle,int timeStyle)来建立DateFormat对象来显示时间和日期。这个方法表明你想要的日期和时间格式。如果你喜欢使用缺省格式，可以使用getDateTimeInstance()来代替它。
你可以使用静态方法getTimeInstance(int timeStyle)创建DateFormat对象来显示正确的时间。
下面的程序示范了getDateTimeInstance()和getTimeInstance()怎样工作：

&#160;查看代码 JAVA1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.*;
import java.text.*;
&#160;
public class Apollo &#123;
public static void main&#40;String&#91;&#93; args&#41; &#123;
GregorianCalendar liftOffApollo11 = [...]]]></description>
		<wfw:commentRss>http://laigw.name/post/19.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>＜＜Thinking in Java＞＞ 3th Edition 读书笔记</title>
		<link>http://laigw.name/post/16.html</link>
		<comments>http://laigw.name/post/16.html#comments</comments>
		<pubDate>Fri, 14 Nov 2008 12:13:35 +0000</pubDate>
		<dc:creator>Gavin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Thinking]]></category>
		<category><![CDATA[读书笔记]]></category>

		<guid isPermaLink="false">http://www.laigw.name/?p=16</guid>
		<description><![CDATA[一、第一章 对象导论
1、Alan Kay总结了面向对象的五个特性：
1) 万物皆为对象
2) 程序是对象的集合，它们通过发送消息来告知彼此所要做的
3) 每个对象都有自己的由其他对象所构成的存储
4) 每个对象都有其类型
5) 某一特定类型的所有对象都可以接收同样的消息
Booch的描述：对象具有状态、行为和标识。

2、UML：Unified Modelling Language, 统一建模语言。

3、通过继承而产生的类型具有等价性，即：导出类与基类具有相同的类型。
4、使基类与导出类产生差异的两种方法：
1) 直接在导出类中添加新方法(is-like-a)
2) 改变现有基类的方法的行为－－覆盖(overriding)，这叫替代原则，即“纯粹替代”(is-a)
5、多态使用了“后期绑定”的概念，它通过“向上转型”(upcasting)来实现。
6、抽象方法(abstract)只能在抽象类内部创建，当该类被继承时，抽象方法必须被实现，否则继承类仍然是一个抽象类。
7、Java完全采用在被称为堆(heap)的内存池中动态地创建对象。每当想要创建新的对象时，就要使用new关键字来构建此对象的实例。与此不同的是，C++除了在堆中创建对象外，还可以在堆栈中创建对象。
8、Java的单根继承结构，使垃圾回收器的实现变得容易。
二、第二章 一切都是对象
1、存储数据的六个地方
1) 寄存器：编译器决定
2) 堆栈: 堆栈指针若向下移动，则分配新的内存；
若向上移动，则释放那些内存。
对象的引用而非对象存在此。
3) 堆：存放所有的Java对象；
4) 静态存储：RAM中固定的位置；
5) 常量存储：代码区内部；
6) 非RAM存储：如“流对象”和“持久化对象”。
2、虽然Java把一切都可视为对象，但基本类型却是一个特例，它与两种形式存活于Java中：基本类型和对象。

3、Java基本类型所占存储空间的大小具有不变性，即不随机器硬件架构的变化而变化。
4、两个高精度计算类：BigInteger和BigDecimal。
5、数组也具有数组对象和基本类型数组两种。
6、Java不支持类似C/C++将一个较大作用域的变量“隐藏”起来的做法。
7、当变量作为类的成员使用时，Java才确保给定其默认值，以确保那些是基本类型的成员变量得到初始化，防止产生程序错误。但该规则不适用于局部变量。所以使用一个局部变量前必须对其初始化，否则Java会在编译时返回一个错误。
8、对于static方法，不能简单地通过调用其他非static成员或方法而没有指定某个命名对象，来直接访问非static成员或方法(因为非static成员或方法必须与某一种特定对象关联)。
9、注释文档(javadoc): /** some comment */
(1) 使用javadoc的方式主要有两种：嵌入HTML和“文档标签”
(2) 文档标签：
独立文档标签：以&#8221;@&#8221;字符开头的命令，且要置于注释行的最前面(但是不算前导&#8221;*&#8221;之后的最前面)；
行内文档标签：以&#8221;@&#8221;字符开头，括在花括号内，可以出现在javadoc注释中的内任何地方。
(3) 三种类型的注释文档：
·位于类定义之前
·位于变量定义之前
·位于方法定义之前
(4) javadoc只能为&#8221;public&#8221;和&#8221;protected&#8221;成员进行文档注释。&#8221;private&#8221;和包内可访问成员的注释会被忽略掉。
(5) 不要在嵌入式HTML中使用标题标签，如&#60;hl&#62;或&#60;hr&#62;，因为javadoc会插入自己的标题，而你的标题可能同它们发生冲突。
(6) 一些标签示例
&#60;1&#62;@see: 引用其他类。格式：
@see classname
@see fully-qualified-classname
@see fully-qualified-classname # method -name
&#60;2&#62;{@link package.class#member label} 功能同@see
&#60;3&#62;{@docRoot} 产生到文档根目录的相对路径，用于文档树页面的文档注释中。
&#60;4&#62;@version:
@version version-information
&#60;5&#62;@author:
@author author-information
&#60;6&#62;@since 该标签允许你指定程序代码最早使用的版本
&#60;7&#62;@param 该标签用于方法文档中，形式如下：
@param parameter-name description
&#60;8&#62;@return
@return description
&#60;9&#62;@throws: 描述抛出的异常
@throws fully-qualified-class-name description
&#60;10&#62;@deprecated:该标签用于指出一些旧特性已由改进的新特性所取代。
三、第三章 控制程序流程
1、当关系操作符作用于对象时(&#60;,&#62;,&#60;=,&#62;=,==,!=)，关系比较的仅仅是对象的引用。
2、“与”、“或”、“非”操作只可应用于布尔值。不同于C/C++，不可将一个非布尔值当作布尔值在逻辑表达式中的使用。
3、移位操作符：
左移(&#60;&#60;)：将操作符左边的操作数向左移动操作符右侧指定的位数(在低位补0)
&#124;-“有符号”右移(&#62;&#62;)：将操作符左边的操作数向右移动操作符右侧指定的位数。
&#124; 　　　　　　“符号扩展”：若符号为正，则在高位插入0；
右移(&#62;&#62;):&#60; 　　　　　　　　　　若符号为负，则在高位插入1。
&#124;
&#124;-“无符号”右移(&#62;&#62;&#62;)：“零扩展”：无论正负，都在高位插0
左乘右除准则：　左移一位，相当于乘2^1
右移一位，相当于除2^1
4、非但变量、数值也可以进行类型转换
5、只有for循环才具备在控制表达式里定义变量的能力，其他任何条件语句或循环语句，都不可采用这种方法
6、break和continue语句的规则：
1)一般的continue会退回最内层循环的开头(顶部)，并继续执行；
2)带标签的continue会到达标签的位置，并重新进入紧接在那个标签后面的循环；
3)一般的break会中断并跳出当前循环
4)带标签的break会中断并跳出标签所指定的循环，抵达该循环的末尾处。
7、在Java里需要使用标签的唯一理由就是因为有循环嵌套，而且你想从多层嵌套中break或continue。此外，标签要刚好处于要跳转到的循环之前，如：
label1:
outer_iteration{
inner_iteration{
//&#8230;
break; [...]]]></description>
		<wfw:commentRss>http://laigw.name/post/16.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

