??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲伊人tv综合网色,亚洲国产成人久久综合碰碰动漫3d,久久九九亚洲精品http://www.tkk7.com/bacoo/category/28259.html鉴证我学?fn)Java的历E!zh-cnTue, 11 Mar 2008 22:07:58 GMTTue, 11 Mar 2008 22:07:58 GMT60assert使用结http://www.tkk7.com/bacoo/archive/2008/03/11/185491.htmlbacoobacooTue, 11 Mar 2008 14:00:00 GMThttp://www.tkk7.com/bacoo/archive/2008/03/11/185491.htmlhttp://www.tkk7.com/bacoo/comments/185491.htmlhttp://www.tkk7.com/bacoo/archive/2008/03/11/185491.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/185491.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/185491.htmlassert expression1;
assert expression1:expression2;
如果expression1为trueQ则不抛出错误,E序正常q行Qexpression2也不会执行?br /> 如果expression1为falseQ则抛出异常Q程序中断蟩出,expression2执行?/p>

一般来_不要在expression1、expression2中用函数的q回|
不要其使用在public函数中检查输入参敎ͼ但可以用于private函数中检输入参数?br />

使用Ӟ~译旉要用javac -sourceQ执行时需要用java -ea?br />


个h的一点理解:使用assert只是Z帮助我们调试E序Q因此用assert所遵@的原则就?#8220;不能因ؓ有了assert的存在而ɽE序的结构发生Q何的改变”Q说白了是“如果把assert部分删除了,E序依然不会有Q何的问题Q只不过不能帮助我们查出一些错误来?#8221;Q因此用assert的时候不应该在表辑ּ中用函敎ͼ因ؓ一旦把q句assert语句删除后,E序的结构就改变了,q不W合上述提到的原则!

 

 附上一写得很不错的原文:

深入解析Java的assertion

一、assertion的语法和语义

    J2SE 1.4在语a上提供了一个新Ҏ(gu),是assertion(断言)功能Q它是该版本在Java语言斚w最大的革新。在软g开发中Qassertion是一U经典的调试、测试方式,本文深入解析assertion功能的用以及其设计理念Qƈl出相关的例??/p>

     assertion(断言)在Y件开发中是一U常用的调试方式Q很多开发语a中都支持q种机制Q如CQC++和Eiffel{,但是支持的Ş式不相同,有的是通过语言本n、有的是通过库函数等。另外,从理Z来说Q通过assertion方式可以证明E序的正性,但是q是一相当复杂的工作Q目前还没有太多的实跉|义?/p>

      在实CQassertion是在程序中的一条语句,它对一个boolean表达式进行检查,一个正程序必M证这个boolean表达式的gؓtrueQ如果该gؓfalseQ说明程序已l处于不正确的状态下Q系l将l出警告或退出。一般来_assertion用于保证E序最基本、关键的正确性。assertion查通常在开发和试时开启。ؓ了提高性能Q在软g发布后,assertion查通常是关闭的。下面简单介l一下Java中assertion的实现?/p>

1Q?) 语法表示

在语法上Qؓ了支持assertionQJava增加了一个关键字assert。它包括两种表达式,分别如下Q?/p>

  1. assert expression1;
  2. assert expression1: expression2;

在两U表辑ּ中,expression1表示一个boolean表达式,expression2表示一个基本类型或者是一个对?Object) Q基本类型包括boolean,char,double,float,int和long。由于所有类都ؓObject的子c,因此q个参数可以用于所有对象?/p>

1Q?) 语义含义

在运行时Q如果关闭了assertion功能Q这些语句将不vM作用。如果打开了assertion功能Q那么expression1的值将被计,如果它的gؓfalseQ该语句强抛Z个AssertionError对象。如果assertion语句包括expression2参数Q程序将计算出expression2的结果,然后这个结果作为AssertionError的构造函数的参数Q来创徏AssertionError对象Qƈ抛出该对象;如果expression1gؓtrueQexpression2不被计?/p>

一U特D情冉|Q如果在计算表达式时Q表辑ּ本n抛出ExceptionQ那么assert停止运行,而抛个Exception?/p>

1Q?) 一些assertion例子

下面是一些Assert的例子?/p>

  1. assert  0 < value;
  2. assert  0 < value:"value="+value;
  3. assert  ref != null:"ref doesn't equal null";
  4. assert  isBalanced();

1Q?) ~译

׃assert是一个新关键字,使用老版本的JDK是无法编译带有assert的源E序。因此,我们必须使用JDK1.4(或者更?的Java~译器,在用Javac命oӞ我们必须加上-source 1.4作ؓ参数?source 1.4表示使用JDK 1.4版本的方式来~译源代码,否则~译׃能通过Q因为缺省的Javac~译器用JDK1.3的语法规则?/p>

一个简单的例子如下Q?/p>

javac      -source   1.4    test.java

1Q?) q行

׃带有assert语句的程序运行时Q用了新的ClassLoader和Classc,因此Q这U程序必dJDK1.4(或者更高版?的JRE下运行,而不能在老版本的JRE下运行?/p>

׃我们可以选择开启assertion功能Q或者不开启,另外我们q可以开启一部分cL包的assertion功能Q所以运行选项变得有些复杂。通过q些选项Q我们可以过滤所有我们不兛_的类Q只选择我们兛_的类或包来观察。下面介l两cd敎ͼ

  1. 参数 -esa ?-dsaQ?br /> 它们含义为开?关闭)pȝcȝassertion功能。由于新版本的Java的系l类中,也了assertion语句Q因此如果用户需要观察它们的q行情况Q就需要打开pȝcȝassertion功能 Q我们可使用-esa参数打开Q?-dsa参数关闭?br /> -esa?dsa的全名ؓ-enablesystemassertions?disenablesystemassertionsQ全名和~写名有同样的功能?br />  
  2. 参数 -ea?strong>-eaQ?br /> 它们含义为开?关闭)用户cȝassertion功能Q通过q个参数Q用户可以打开某些cL包的assertion功能Q同L(fng)户也可以关闭某些cd包的assertion功能。打开assertion功能参数?eaQ如果不带Q何参敎ͼ表示打开所有用L(fng)Q如果带有包名称或者类名称Q表C打开q些cL包;如果包名U后面跟有三个点Q代表这个包及其子包Q如果只有三个点Q代表无名包。关闭assertion功能参数?daQ用方法与-eacM?br /> -ea?da的全名ؓ-enableassertions?disenableassertionsQ全名和~写名有同样的功能?br /> 下面表格表示了参数及其含义,q有例子说明如何使用?br />  
    参数 例子 说明
    -ea java -ea 打开所有用L(fng)的assertion
    -da java -da 关闭所有用L(fng)的assertion
    -ea:<classname> java -ea:MyClass1 打开MyClass1的assertion
    -da:<classname> java -da: MyClass1 关闭MyClass1的assertion
    -ea:<packagename> java -ea:pkg1 打开pkg1包的assertion
    -da:<packagename> java -da:pkg1 关闭pkg1包的assertion
    -ea:... java -ea:... 打开~省?无名?的assertion
    -da:... java -da:... 关闭~省?无名?的assertion
    -ea:<packagename>... java -ea:pkg1... 打开pkg1包和其子包的assertion
    -da:<packagename>... java -da:pkg1... 关闭pkg1包和其子包的assertion
    -esa java -esa 打开pȝcȝassertion
    -dsa java -dsa 关闭pȝcȝassertion
    l合使用 java -dsa:MyClass1:pkg1 关闭MyClass1和pkg1包的assertion

    其中...代表Q此包和其子包的含义。例如我们有两个包ؓpkg1和pkg1.subpkg。那么pkg1...׃表pkg1和pkg1.subpkg两个包?br /> 另外QJavaZ让程序也能够动态开启和关闭某些cd包的assertion功能QJava修该了Class和ClassLoader的实玎ͼ增加了几个用于操作assert的API。下面简单说明一下几个API的作用?br /> ClassLoadercM的几个相关的API:
      setDefaultAssertionStatus:用于开?关闭assertion功能
      setPackageAssertionStatus:用于开?关闭某些包的assertion功能
      setClassAssertionStatus: 用于开?关闭某些cȝassertion功能
      clearAssertionStatusQ用于关闭assertion功能
     

二、assertion的设计问?/span>

      首先Q我们认为assertion是必要的。因为,如果没有l一的assertion机制QJavaE序通常使用if-then-else或者switch-case语句q行assertion查,而且查的数据cd也不完全相同。assertion机制让JavaE序员用l一的方式处理assertion问题Q而不是按自己的方式处理。另外,如果用户使用自己的方式进行检查,那么q些代码在发布以后仍然将起作用,q可能会影响E序的性能。而从语言a层次支持assertion功能Q这把assertionҎ(gu)能带来的负面媄响降到最?/p>

      Java是通过增强一个关键字assert实现支持assertionQ而不是用一个库函数支持Q这说明Java认ؓassertion对于语言本n来说是非帔R要的。实际上Q在Java的早期的规范中,Java是能够支持assert的,但是׃一些实现的限制Q这些特性从规范中除M。因此,assert的再ơ引入应该是恢复了Java对assert的支持。C语言是通过Assert.h函数库实现断a的支持?/p>

      Java的assertion的开启也和C语言不太一P我们都知道在C语言中,assertion的开启是在编译时候决定的。当我们使用debug方式~译E序时候,assertion被开启,而用release方式~译时候,assertion自动被关闭。而Java的assertion却是在运行的时候进行决定的。其实,q两U方式是各有优缺炏V如果采用编译时军_方式Q开发h员将处理两种cd的目标码Qdebug版本和release版本Q这加大了文管理的隑ֺQ但是提高了代码的运行效率。Java采用q行时决定的方式Q这h有的assertion信息置于目标代码中Q同一目标代码可以选择不同方式q行Q增强目标代码的灉|性,但是它将牺牲因ؓassertion而引起一部分性能损失。Java专家组认ؓQ所牺牲的性能相当,因此java采用了运行时军_方式?/p>

      另外Q我们注意到AssertionError作ؓError的一个子c,而不是RuntimeException。关于这一点,专家l也q行了长期的讨论。Error代表一些异常的错误Q通常是不可以恢复的,而RuntimeException该错误在q行时才发生的特炏VAssertionError通常为非常关键的错误Q这些错误往往是不Ҏ(gu)恢复的,而且assertion机制也不鼓励E序员对q种错误q行恢复。因此,Zassertion的含义,Java专家组选择了让AssertError为Error的子cR?/p>

三、assertion与?/span>

       在本节,我们考虑assertion与承的关系Q研Iassert是如何定位的。如果开启一个子cȝassertionQ那么它的父cȝassertion是否执行Q?/p>

       下面的例子将昄如果一个assert语句在父c,而当它的子类调用它时Q该assert为false。我们看看在不同的情况下Q该assertion是否被处理?/p>

class Base
{
public void baseMethod()
{
assert      false : "Assertion failed:This is base ";// Lassertionp|
System.out.println("Base Method");
}
}
class Derived
extends Base
{
public void derivedMethod()
{
assert false: "Assertion failed:This is derive";// Lassertionp|
System.out.println( "Derived Method" );
}
public static void main( String[] args )
{
try
{
Derived derived = new Derived();
derived.baseMethod(  );
derived.derivedMethod();
}
catch( AssertionError ae )
{
System.out.println(ae);
}
}
}

q行命o 含义 l果
Java Derived 不启用assertion Base Method
Derived Method
Java -ea Derived 开启所有assertion Java.lang.AssertionError:Assertion Failed:This is base
Java -da Derived 关闭所有assertion Base Method
Derived Method
Java -ea:Base Derived 仅打开Base的assertion Java.lang.AssertionError:Assertion Failed:This is base
Java -ea:Derived Derived 仅打开Derived的assertion Base Method
Java.lang.AssertionError:Assertion Failed:This is derived

       从这个例子我们可以看出,父类的assert语句只有在父类的assert开启才起作用,如果仅仅开启子cȝassertQ父cȝassert仍然不运行。例如,我们执行java -ea:Derived Derived的时候,Basecȝassert语句q不执行。因此,我们可以认ؓQassert语句不具有承功能?/p>

四、assertion的?/span>

       assertion的用是一个复杂的问题Q因涉及到E序的风|assertionq用的目标,E序的性质{问题。通常来说Qassertion用于查一些关键的|q且q些值对整个E序Q或者局部功能的完成有很大的影响Qƈ且这U错误不Ҏ(gu)恢复的。assertion表达式应该短、易懂,如果需要评估复杂的表达式,应该使用函数计算。以下是一些用assertion的情늚例子Q这些方式可以让javaE序的可靠性更高?/p>

  1. 查控制流Q?在if-then-else和swith-case语句中,我们可以在不应该发生的控制支上加上assert false语句。如果这U情况发生了Qassert能够查出来?br /> 例如Qx取值只能1,2,3Q我们的E序可以如下表示
     
    	switch (x)
        { case 1: …;
        case 2: …;
        case 3: …
        default: assert false:"x value is invalid: "+x;
        }
        
  2. 在私有函数计前Q检查输入参数是否有效;对于一U有些函敎ͼ要求输入满一些特定的条gQ那么我们可以在函数开始处使用assertq行参数查。对于公共函敎ͼ我们通常不用assertion查,因ؓ一般来_公共函数必须Ҏ(gu)效的参数q行查和处理。而私有函数往往是直接用的?br /> 例如Q某函数可能要求输入的参数必M为null。那么我们可以在函数的一开始加?assert parameter1!=null : "paramerter is null in test method";
  3. 在函数计后Q检查函数结果是否有效;对于一些计函敎ͼ函数q行完成后,某些值需要保证一定的性质Q因此我们可以通过assert查该倹{?br /> 例如Q我们有一个计绝对值的函数Q那么我们就可以在函数的l果处,加上一个语句:
     
    assert  value>=0:"Value should be bigger than 0:"+value;
    通过q种方式Q我们可以对函数计算完的l果q行查?
  4. 查程序不变量Q有些程序中Q存在一些不变量Q在E序的运行生命周期,q些不变量的值都是不变的。这些不变量可能是一个简单表辑ּQ也可能是一个复杂的表达式。对于一些关键的不变量,我们可以通过assertq行查?br /> 例如Q在一个胦会系l中Q公司的支出和收入必M持一定的q关系Q因此我们可以编写一个表辑ּ查这U^衡关p,如下表示?br />  
              private boolean isBalance() {
        ……
        }
        
    在这个系l中Q在一些可能媄响这U^衡关pȝҎ(gu)的前后,我们都可以加上assert验证Qassert isBalance():"balance is destoried";
     

五、结?/span>

        assertion为开发h员提供了一U灵zd调试和测试机Ӟ它的使用也非常简单、方ѝ但是,如何规范、系l地使用assertion(特别是在Java语言?仍然是一个亟待研I的问题?br />
关于作?/span>
Ƨ阳辎ͼ北京大学计算机系士毕业Q?8qv开始研I基于java的Y件开发、测试,参与开发、测试过多个ZJava的应用程序和W(xu)eb服务目。联pL?a href="mailto:yeekee@sina.com">mailto:yeekee@sina.com
周欣Q北京大学计机pdd士生Q主要研I方向:E序理解、逆向工程及Y件度量,联系方式 zhouxin@sei.pku.edu.cn?/td>



bacoo 2008-03-11 22:00 发表评论
]]>
U程Ҏ(gu)interrupt的说?/title><link>http://www.tkk7.com/bacoo/archive/2008/02/23/181622.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Sat, 23 Feb 2008 11:13:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2008/02/23/181622.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/181622.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2008/02/23/181622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/181622.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/181622.html</trackback:ping><description><![CDATA[<p>U程的interruptҎ(gu)很特D,有必要在q里着重说明一下?br /> interruptedҎ(gu)是查询是否有“中断状?#8221;q一标志Q而这一标志很重要很重要?br /> 通常情况下这个标志都是没有被讄的,一旦这个标志被讄了,则所有当前正在阻塞的Ҏ(gu)Q限定在׃wait、sleep、join三种Ҏ(gu)引发的阻塞)都会立刻完成“跛_d状态、抛出InterruptedException异常、清除中断状态标?#8221;q三件工作。仿?jng)线E在dӞd不断的查询这一标志Q一旦发现这个标志被讄了,那么qd生上q提到的三g工作。不q这只是一U猜,至于底层到底是如何实现的Q我们ƈ不知道?/p> <p>而我们调用interruptҎ(gu)也很有趣Q通常q个标志都是未被讄的,一旦调用这个方法,它就会设|这个标志,说白了,q个Ҏ(gu)所完成的工作也׃仅限于设|了一个这L(fng)标志。接下来p和上一D落中提到的事情相关联了Q如果线E当前是d的状态,那么它会利用q个标志啦,然后?#8220;三g事情”Q然后这个标志又被清除了Q如果线E当前是非阻塞状态,那么该方法的调用也就仅仅是设|一个标志而已Q注意设|了q个标记和没设|这个标记完全不同了Q一旦你再想调用sleep{阻塞方法时Q它们都?#8220;立刻跛_d状态、抛出异常、清除标?#8221;啦,呵呵?/p> <p>xQ终于清除了interruptҎ(gu)的作用了吧?</p> <img src ="http://www.tkk7.com/bacoo/aggbug/181622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2008-02-23 19:13 <a href="http://www.tkk7.com/bacoo/archive/2008/02/23/181622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于serialVersionUIDhttp://www.tkk7.com/bacoo/archive/2008/01/07/173450.htmlbacoobacooMon, 07 Jan 2008 13:12:00 GMThttp://www.tkk7.com/bacoo/archive/2008/01/07/173450.htmlhttp://www.tkk7.com/bacoo/comments/173450.htmlhttp://www.tkk7.com/bacoo/archive/2008/01/07/173450.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/173450.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/173450.htmlserialVersionUID的解?Q?br /> 前两天升U了Eclipse?.1版本Q在老版本的IDE环境中写的程序在Problems中会出来好多cM的警告。当采用E序的自动修复时Q采用默认方

式,Eclipse会加上:private static final long serialVersionUID = 1L;
  其实q个问题倒也不媄响程序的q行Q但是我看到Problems里面有警告就不舒服,同时也说明我们写的代码还是不规范。不怕,我们有互

联网查查是怎么回事Q具体的原因q就是和序列化中的这个serialVersionUID有关?br />   
  serialVersionUID 用来表明cȝ不同版本间的兼容性。如果你修改了此c? 要修Ҏ(gu)倹{否则以前用老版本的cd列化的类恢复时会出错

?br />   
  在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生q个serialVersionUIDQ对于Test.classQ执行命令:serialver Test?/p>

  Z在反序列化时Q确保类版本的兼Ҏ(gu),最好在每个要序列化的类中加入private static final long serialVersionUIDq个属性,?/p>

体数D己定义。这P即某个cd与之对应的对象已l序列化出去后做了修改,该对象依然可以被正确反序列化。否则,如果不显式定?/p>

该属性,q个属性值将由JVMҎ(gu)cȝ相关信息计算Q而修改后的类的计结果与修改前的cȝ计算l果往往不同Q从而造成对象的反序列化因

为类版本不兼容而失败?/p>

  不显式定义这个属性值的另一个坏处是Q不利于E序在不同的JVM之间的移植。因Z同的~译器实现该属性值的计算{略可能不同Q从?/p>

造成虽然cL有改变,但是因ؓJVM不同Q出现因cȝ本不兼容而无法正反序列化的现象出现?/p>

  
serialVersionUID作用Q?
序列化时Z保持版本的兼Ҏ(gu),卛_版本升时反序列化仍保持对象的唯一性?

你可以随便写一个,在Eclipse中它替你生成一个,有两U生成方式:
一个是默认?LQ比如:private static final long serialVersionUID = 1L;
一个是Ҏ(gu)cd、接口名、成员方法及属性等来生成一?4位的哈希字段Q比如:private static final long serialVersionUID = -

8940196742313994740L;之类的?/p>

当你一个类实现了Serializable接口Q如果没有定义serialVersionUIDQEclipse会提供这个提C功能告诉你d义之?
在Eclipse中点ȝ中warning的图标一下,Eclipse׃自动l定两种生成的方式,如上面所q。如果不惛_义它Q在Eclipse的设|中也可?/p>

把它x的,讄如下Q?
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems
Serializable class without serialVersionUID的warningҎ(gu)ignore卛_?

如果你没有考虑到兼Ҏ(gu)问题时Q就把它xQ不q有q个功能是好的,q个serialVersionUIDZ让该cdSerializable向后兼容?

如果你的cSerialized存到盘上面后,可是后来你却更改了类别的field(增加或减或改名)Q当你DeserializeӞ׃出现Exception的,

q样׃造成不兼Ҏ(gu)的问题?

但当serialVersionUID相同Ӟ它就会将不一L(fng)field以type的预讑րDeserializeQ这个可以避开不兼Ҏ(gu)的问题?br />



bacoo 2008-01-07 21:12 发表评论
]]>
JavacM的限定词http://www.tkk7.com/bacoo/archive/2008/01/07/173341.htmlbacoobacooMon, 07 Jan 2008 06:37:00 GMThttp://www.tkk7.com/bacoo/archive/2008/01/07/173341.htmlhttp://www.tkk7.com/bacoo/comments/173341.htmlhttp://www.tkk7.com/bacoo/archive/2008/01/07/173341.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/173341.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/173341.htmljava语言中有四种不同的限定词Q提供了四种不同的访问权限?/p>

  1Q?private
  cM限定为private的成员,只能被这个类本n讉K?br />   如果一个类的构造方法声明ؓprivate,则其它类不能生成该类的一个实例?/p>

  2Q?default
  cM不加M讉K权限限定的成员属于缺省的QdefaultQ访问状态,可以被这个类本n和同一个包中的cL讉K?/p>

  3Q?protected
  cM限定为protected的成员,可以被这个类本n、它的子c(包括同一个包中以及不同包中的子类Q和同一个包中的所有其他的c访问?/p>

  4Q?public
  cM限定为public的成员,可以被所有的c访问?/p>

  ?-1列出了这些限定词的作用范围?/p>

【表3-1】 java中类的限定词的作用范围比?br />   =============================================================
||              同一个类  同一个包的类 不同包的子类  不同包非子类    ||
|| private     *                                                                                              ||
|| default     *                   *                                                                         ||
|| protected *                   *                              *                                        ||
|| public      *                   *                              *                        *              ||
  =============================================================
说明Q上面这个表Q看h很简单,而且也很Ҏ(gu)记忆Q但是却蕴含着极ؓ丰富的信息,可以从不同的角度来理解上面的q个表?br /> 比如在同一个类里面Ӟ四个关键词都相当于是publicQ可以不在乎限定词是什么;在同一个包里面Ӟ除了private限定词外Q所有的限定词的作用都完全等同于public。我们经怼思考这样一个问题:一个类的属性和Ҏ(gu)是否对外可见Q这个问题描qC提到?#8220;可见”二字Q当环境?#8220;非子c?#8221;Ӟ说白了就是我们能否通过实例化这个类后,用一个对象把q个cȝq些字段或者方法给“?#8221;出来Q即“某对?某属性(或某Ҏ(gu)Q?#8221;。因为通常我们都是在不同包的环境下操作的,比如我们会import很多pȝ的包中的c,诸如“import java.awt.*;”q样的语句,因此我们使用q些包中的类Ӟ它们Ҏ(gu)们的可见也就仅仅局限在使用“public”限定词修饰的属性或Ҏ(gu)上了Q因此大家往往会误以ؓ只有public的东西才能点出来Q实则不Ӟ当我们在同一个包中的非子cM也可以把除了private修饰的东西之外的所有属性和Ҏ(gu)l?#8220;?#8221;出来。其实对?#8220;?#8221;q个q算Q可以分两个角度ȝ解,既然能用?#8220;?#8221;操作Q那׃表了我们使用的环境应该是“非子c?#8221;Q非子类又可以分?#8220;包内”?#8220;非包?#8221;Q对?#8220;包内”Q只要不是private修饰的东襉K能点出来Q对?#8220;非包?#8221;则只能是public的东西才能点出来Q;Q如果是?#8220;子类”中操作时Q大家可以思考一下,我们q用“?#8221;操作吗?昄不用了,因ؓ在子cMQ父cM定义的东西只要可见的话都可以被你拿过来用Q因此根本就用不到点操作Q当然这里也要分“包内”?#8220;非包?#8221;。对于default限定词,我们不能昄的用它来定义属性或Ҏ(gu)Q只要我们在定义属性或Ҏ(gu)的前面什么限定词都不加,默认的使用了default限定词?/p>

bacoo 2008-01-07 14:37 发表评论
]]>
[转蝲]Java垃圾攉法http://www.tkk7.com/bacoo/archive/2008/01/02/172047.htmlbacoobacooTue, 01 Jan 2008 17:56:00 GMThttp://www.tkk7.com/bacoo/archive/2008/01/02/172047.htmlhttp://www.tkk7.com/bacoo/comments/172047.htmlhttp://www.tkk7.com/bacoo/archive/2008/01/02/172047.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/172047.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/172047.html
Java语言建立了垃圾收集机Ӟ用以跟踪正在使用的对象和发现q回收不再用(引用Q的对象。该机制可以有效防范动态内存分配中可能发生的两个危险:因内存垃圾过多而引发的内存耗尽Q以及不恰当的内存释放所造成的内存非法引用?br />
垃圾攉法的核心思想是:对虚拟机可用内存I间Q即堆空间中的对象进行识别,如果对象正在被引用,那么U其为存?gu)zd象,反之Q如果对象不再被引用Q则为垃圑֯象,可以回收其占据的I间Q用于再分配。垃圾收集算法的选择和垃圾收集系l参数的合理调节直接影响着pȝ性能Q因此需要开发h员做比较深入的了解?br />


2Q触发主GCQGarbage CollectorQ的条g

JVMq行ơGC的频率很?但因UGC占用旉极短,所以对pȝ产生的媄响不大。更值得x的是主GC的触发条?因ؓ它对pȝ影响很明显。ȝ来说,有两个条件会触发主GC:

①当应用E序I闲?x有应用线E在q行?GC会被调用。因为GC在优先最低的U程中进?所以当应用忙时,GCU程׃会被调用,但以下条仉外?br />
②Java堆内存不x,GC会被调用。当应用U程在运?q在q行q程中创建新对象,若这时内存空间不?JVM׃强制地调用GCU程,以便回收内存用于新的分配。若GC一ơ之后仍不能满内存分配的要?JVM会再q行两次GC作进一步的试,若仍无法满要求,?JVM报“out of memory”的错?Java应用停止?br />
׃是否q行主GC由JVMҎ(gu)pȝ环境军_,而系l环境在不断的变化当?所以主GC的运行具有不定?无法预计它何时必然出?但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的?br />


3Q减GC开销的措?br />
Ҏ(gu)上述GC的机?E序的运行会直接影响pȝ环境的变?从而媄响GC的触发。若不针对GC的特点进行设计和~码,׃出现内存ȝ{一pd负面影响。ؓ了避免这些媄?基本的原则就是尽可能地减垃圑֒减少GCq程中的开销。具体措施包括以下几个方?

(1)不要昑ּ调用System.gc()

此函数徏议JVMq行主GC,虽然只是而非一?但很多情况下它会触发主GC,从而增加主GC的频?也即增加了间歇性停的ơ数?br />


(2)量减少临时对象的?br />
临时对象在蟩出函数调用后,会成为垃?用临时变量q当于减少了垃圄产生,从而g长了出现上述W二个触发条件出现的旉,减少了主GC的机会?br />


(3)对象不用时最好显式置为Null

一般而言,为Null的对象都会被作ؓ垃圾处理,所以将不用的对象显式地设ؓNull,有利于GC攉器判定垃?从而提高了GC的效率?br />


(4)量使用StringBuffer,而不用String来篏加字W串Q详见blog另一文章JAVA中String与StringBufferQ?br />
׃String是固定长的字W串对象,累加String对象?q在一个String对象中扩?而是重新创徏新的String对象,如Str5=Str1+Str2+Str3+Str4,q条语句执行q程中会产生多个垃圾对象,因ؓҎ(gu)?#8220;+”操作旉必须创徏新的String对象,但这些过渡对象对pȝ来说是没有实际意义的,只会增加更多的垃圾。避免这U情况可以改用StringBuffer来篏加字W串,因StringBuffer是可变长?它在原有基础上进行扩?不会产生中间对象?br />


(5)能用基本cd如Int,Long,׃用Integer,Long对象

基本cd变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好用基本变量?br />


(6)量用静态对象变?br />
静态变量属于全局变量,不会被GC回收,它们会一直占用内存?br />


(7)分散对象创徏或删除的旉

集中在短旉内大量创建新对象,特别是大对象,会导致突焉要大量内?JVM在面临这U情冉|,只能q行主GC,以回收内存或整合内存片,从而增加主GC的频率。集中删除对?道理也是一L(fng)。它使得H然出现了大量的垃圾对象,I闲I间必然减少,从而大大增加了下一ơ创建新对象时强制主GC的机会?br />


4Qgc与finalizeҎ(gu)

⑴gcҎ(gu)h垃圾回收

使用System.gc()可以不管JVM使用的是哪一U垃圑֛收的法Q都可以hJava的垃圑֛收。需要注意的是,调用System.gc()也仅仅是一个请求。JVM接受q个消息后,q不是立卛_垃圾回收Q而只是对几个垃圾回收法做了加权Q垃圾回收操作Ҏ(gu)发生Q或提早发生Q或回收较多而已?br />


⑵finalizeҎ(gu)透视垃圾攉器的q行

在JVM垃圾攉器收集一个对象之?Q一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下QJava提供了缺省机制来l止化该对象释放资源Q这个方法就是finalizeQ)。它的原型ؓQ?br />
protected void finalize() throws Throwable

在finalize()Ҏ(gu)q回之后Q对象消失,垃圾攉开始执行。原型中的throws Throwable表示它可以抛ZQ何类型的异常?br />
因此Q当对象卛_被销毁时Q有旉要做一些善后工作。可以把q些操作写在finalize()Ҏ(gu)里?br />
protected void finalize()

{

// finalization code here

}



⑶代码示?br />


class Garbage

{

int index;

static int count;

Garbage()

{

count++;

System.out.println("object "+count+" construct");

setID(count);

}



void setID(int id)

{

index=id;

}



protected void finalize() //重写finalizeҎ(gu)

{

System.out.println("object "+index+" is reclaimed");

}



public static void main(String[] args)

{

new Garbage();

new Garbage();

new Garbage();

new Garbage();

System.gc(); //hq行垃圾攉?br />
}

}



5QJava 内存泄漏

׃采用了垃圑֛收机ӞM不可辑֯象(对象不再被引用)都可以由垃圾攉U程回收。因此通常说的Java 内存泄漏其实是指无意识的、非故意的对象引用,或者无意识的对象保持。无意识的对象引用是指代码的开发h员本来已l对对象使用完毕Q却因ؓ~码的错误而意外地保存了对该对象的引用Q这个引用的存在q不是编码h员的主观意愿Q,从而得该对象一直无法被垃圾回收器回收掉Q这U本来以为可以释放掉的却最l未能被释放的空间可以认为是?#8220;泄漏?#8221;?br />
考虑下面的程?在ObjStackcM,使用push和popҎ(gu)来管理堆栈中的对象。两个方法中的烦?index)用于指示堆栈中下一个可用位|。pushҎ(gu)存储Ҏ(gu)对象的引用ƈ增加索引?而popҎ(gu)减小索引值ƈq回堆栈最上面的元素。在mainҎ(gu)?创徏了容量ؓ64的栈,q?4ơ调用pushҎ(gu)向它d对象,此时index的gؓ64,随后?2ơ调用popҎ(gu),则index的值变?2,出栈意味着在堆栈中的空间应该被攉。但事实?popҎ(gu)只是减小了烦引?堆栈仍然保持着寚w些对象的引用。故32个无用对象不会被GC回收,造成了内存渗漏?br />

public class ObjStack {

private Object[] stack;

private int index;

ObjStack(int indexcount) {
stack = new Object[indexcount];
index = 0;
}

public void push(Object obj) {
stack[index] = obj;
index++;
}

public Object pop() {
index--;
return stack[index];
}
}


public class Pushpop {

public static void main(String[] args) {
int i = 0;
Object tempobj;
ObjStack stack1 = new ObjStack(64);//new一个ObjStack对象Qƈ调用有参构造函数。分配stack Obj数组的空间大ؓ64Q可以存64个对象,?开始存储?br /> while (i < 64)
{
tempobj = new Object();//循环new Obj对象Q把每次循环的对象一一存放在stack Obj数组中?br /> stack1.push(tempobj);
i++;
System.out.println("W? + i + "ơ进? + "t");
}
while (i > 32)
{
tempobj = stack1.pop();//q里造成了空间的费?br /> //正确的popҎ(gu)可改成如下所指示,当引用被q回?堆栈删除对他们的引用,因此垃圾攉器在以后可以回收他们?br /> /*
* public Object pop() {index - -;Object temp = stack [index];stack [index]=null;return temp;}
*/
i--;
System.out.println("W? + (64 - i) + "ơ出? + "t");
}
}

}


如何消除内存泄漏

  虽然Java虚拟?JVM)及其垃圾攉?garbage collectorQGC)负责理大多数的内存dQJava软gE序中还是有可能出现内存泄漏。实际上Q这在大型项目中是一个常见的问题。避免内存泄漏的W一步是要弄清楚它是如何发生的。本文介l了~写Java代码的一些常见的内存泄漏陷阱Q以及编写不泄漏代码的一些最?jng)_c一旦发生了内存泄漏Q要指出造成泄漏的代码是非常困难的。因此本文还介绍了一U新工具Q用来诊断泄漏ƈ指出Ҏ(gu)原因。该工具的开销非常,因此可以使用它来L处于生中的pȝ的内存泄漏?br />
垃圾攉器的作用

  虽然垃圾攉器处理了大多数内存管理问题,从而ɾ~程人员的生zd得更L了,但是~程人员q是可能犯错而导致出现内存问题。简单地_GC循环地跟t所有来?#8220;?#8221;对象Q堆栈对象、静态对象、JNI句柄指向的对象,诸如此类Q的引用Qƈ所有它所能到辄对象标记为活动的。程序只可以操纵q些对象Q其他的对象都被删除了。因为GC使程序不可能到达已被删除的对象,q么做就是安全的?br />
  虽然内存理可以说是自动化的Q但是这q不能ɾ~程人员免受思考内存管理问题之苦。例如,分配Q以及释放)内存M有开销Q虽然这U开销对编Eh员来说是不可见的。创Z太多对象的程序将会比完成同样的功能而创建的对象却比较少的程序更慢一些(在其他条件相同的情况下)?br />
  而且Q与本文更ؓ密切相关的是Q如果忘?#8220;释放”先前分配的内存,可能造成内存泄漏。如果程序保留对永远不再使用的对象的引用Q这些对象将会占用ƈ耗尽内存Q这是因动化的垃圾收集器无法证明q些对象不再用。正如我们先前所说的Q如果存在一个对对象的引用,对象p定义为活动的Q因此不能删除。ؓ了确保能回收对象占用的内存,~程人员必须保该对象不能到达。这通常是通过对象字D设|ؓnull或者从集合(collection)中移除对象而完成的。但是,注意Q当局部变量不再用时Q没有必要将其显式地讄为null。对q些变量的引用将随着Ҏ(gu)的退自动清除?br />
  概括地说Q这是内存托管语言中的内存泄漏产生的主要原因:保留下来却永q不再用的对象引用?br />
典型泄漏

  既然我们知道了在Java中确实有可能发生内存泄漏Q就让我们来看一些典型的内存泄漏及其原因?br />
全局集合

  在大的应用程序中有某U全局的数据储存库是很常见的,例如一个JNDI?wi)或一个会话表。在q些情况下,必须注意理储存库的大小。必L某种机制从储存库中移除不再需要的数据?br />
  q可能有多种Ҏ(gu)Q但是最常见的一U是周期性运行的某种清除d。该d验证储存库中的数据QƈU除M不再需要的数据?br />
  另一U管理储存库的方法是使用反向链接(referrer)计数。然后集合负责统计集合中每个入口的反向链接的数目。这要求反向链接告诉集合何时会退出入口。当反向链接数目为零Ӟ该元素就可以从集合中U除了?br />
~存

  ~存是一U数据结构,用于快速查扑ַl执行的操作的结果。因此,如果一个操作执行v来很慢,对于常用的输入数据,可以将操作的结果缓存,q在下次调用该操作时使用~存的数据?br />
  ~存通常都是以动态方式实现的Q其中新的结果是在执行时d到缓存中的。典型的法是:

查结果是否在~存中,如果在,p回结果?br /> 如果l果不在~存中,p行计?br /> 计出来的l果d到缓存中Q以便以后对该操作的调用可以使用?br />   该算法的问题Q或者说是潜在的内存泄漏Q出在最后一步。如果调用该操作时有相当多的不同输入Q就有相当多的l果存储在缓存中。很明显q不是正的Ҏ(gu)?br />
  Z预防q种h潜在破坏性的设计Q程序必ȝ保对于缓存所使用的内存容量有一个上限。因此,更好的算法是Q?br />
查结果是否在~存中,如果在,p回结果?br /> 如果l果不在~存中,p行计?br /> 如果~存所占的I间q大Q就U除~存最久的l果?br /> 计出来的l果d到缓存中Q以便以后对该操作的调用可以使用?br />   通过始终U除~存最久的l果Q我们实际上q行了这L(fng)假设Q在来Q比L(fng)存最久的数据Q最q输入的数据更有可能用到。这通常是一个不错的假设?br />
  新算法将保~存的容量处于预定义的内存范围之内。确切的范围可能很难计算Q因为缓存中的对象在不断变化Q而且它们的引用包|万象。ؓ~存讄正确的大是一w常复杂的dQ需要将所使用的内存容量与索数据的速度加以q?br />
  解决q个问题的另一U方法是使用java.lang.ref.SoftReferencec跟t缓存中的对象。这U方法保证这些引用能够被U除Q如果虚拟机的内存用而需要更多堆的话?br />
ClassLoader

  Java ClassLoaderl构的用ؓ内存泄漏提供了许多可乘之机。正是该l构本n的复杂性ClassLoader在内存泄漏方面存在如此多的问题。ClassLoader的特别之处在于它不仅涉及“常规”的对象引用,q涉及元对象引用Q比如:字段、方法和cR这意味着只要有对字段、方法、类或ClassLoader的对象的引用QClassLoader׃ȝ在JVM中。因为ClassLoader本n可以兌许多cd光态字D,所以就有许多内存被泄漏了?br />
定泄漏的位|?br />
  通常发生内存泄漏的第一个迹象是Q在应用E序中出COutOfMemoryError。这通常发生在?zhn)最不愿意它发生的生产环境中Q此时几乎不能进行调试。有可能是因为测试环境运行应用程序的方式与生产系l不完全相同Q因而导致泄漏只出现在生产中。在q种情况下,需要用一些开销较低的工h监控和查扑ֆ存泄漏。还需要能够无需重启pȝ或修改代码就可以这些工兯接到正在q行的系l上。可能最重要的是Q当q行分析Ӟ需要能够断开工具而保持系l不受干扰?br />
  虽然OutOfMemoryError通常都是内存泄漏的信P但是也有可能应用E序实正在使用q么多的内存Q对于后者,或者必d加JVM可用的堆的数量,或者对应用E序q行某种更改Q它用较?yu)的内存。但是,在许多情况下QOutOfMemoryError都是内存泄漏的信受一U查明方法是不间断地监控GC的活动,定内存使用量是否随着旉增加。如果确实如此,可能发生了内存泄漏?

bacoo 2008-01-02 01:56 发表评论
]]>
[转蝲]详析内部c?/title><link>http://www.tkk7.com/bacoo/archive/2008/01/02/172046.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Tue, 01 Jan 2008 17:53:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2008/01/02/172046.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/172046.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2008/01/02/172046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/172046.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/172046.html</trackback:ping><description><![CDATA[     摘要: 本文主要参照|上的一些相x章、以及thinking in java W三版,对java里面的内部类q行了一个较l的ȝ 内部cL指在一个外部类的内部再定义一个类。内部类作ؓ外部cȝ一个成员,q且依附于外部类而存在的。内部类可ؓ静态,可用protected和private修饰Q而外部类只能使用public和缺省的包访问权限)。内部类主要有以下几c:成员内部cR局部内部类、静态内部类、匿?..  <a href='http://www.tkk7.com/bacoo/archive/2008/01/02/172046.html'>阅读全文</a><img src ="http://www.tkk7.com/bacoo/aggbug/172046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2008-01-02 01:53 <a href="http://www.tkk7.com/bacoo/archive/2008/01/02/172046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[改编]final关键?/title><link>http://www.tkk7.com/bacoo/archive/2008/01/01/171986.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Tue, 01 Jan 2008 06:16:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2008/01/01/171986.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/171986.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2008/01/01/171986.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/171986.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/171986.html</trackback:ping><description><![CDATA[<p>1. final变量不能被改?  <br /> 当利用final修饰一个属性(变量Q的时候,此时的属性成为常量?<br /> 注意JAVA命名规范中常量全部字母大写: <br /> final int AGE=10Q?<br /> 帔R的地址不可改变Q但在地址中保存的|卛_象的属性)是可以改变的?</p> <p>final变量是在整个c被创徏时候被赋|之后׃能改变了?<br /> 对于final变量Q如果在声明的时候和构造的时候均不进行赋|~译出错?</p> <p>对于利用构造方法对final变量q行赋值的时候,此时在构造之前系l设|的默认D覆盖?</p> <p>帔RQ这里的帔R指的是实例常量:x员变量)赋| <br /> ①在初始化的时候通过昑ּ声明赋倹{final int x=3Q?<br /> ②在构造的时候赋倹{?<br /> class A{ <br />  final int x; <br />  public A(){ <br />  x=4; <br />  } <br /> } </p> <p>2. finalҎ(gu)不能被改?  <br /> 利用final定义Ҏ(gu)Q这L(fng)Ҏ(gu)Z个不可覆盖的Ҏ(gu)?<br /> 下面q样׃~译出错Q?br /> class A{<br />  public static void max(){<br />   System.out.println("A:max()");<br />  }<br /> }<br /> class B extends A{<br />  public void max(){<br />  }<br /> } <br /> Z保证Ҏ(gu)的一致性(即不被改变)Q可方法用final定义?<br /> 如果在父cM有final定义的方法,那么在子cM保证调用的是同一个父cL法?<br /> 如果一个方法前有修饰词private或staticQ则pȝ会自动在前面加上final。即private和staticҎ(gu)默认均ؓfinalҎ(gu)?</p> <p>注:cȝ修饰W仅限于abstract、final、public。Final和abstract永远不会同时出现?</p> <p>3. finalcM能被l承;  <br /> final修饰cȝ时候,此类不可被承,即finalcL有子cR这样可以用final保证用户调用时动作的一致性,可以防止子类覆盖情况的发生?<br /> String cd是finalc?Q目的是提供效率保证安全?/p> <img src ="http://www.tkk7.com/bacoo/aggbug/171986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2008-01-01 14:16 <a href="http://www.tkk7.com/bacoo/archive/2008/01/01/171986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转蝲]JAVA打印http://www.tkk7.com/bacoo/archive/2007/12/31/171792.htmlbacoobacooSun, 30 Dec 2007 17:32:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/31/171792.htmlhttp://www.tkk7.com/bacoo/comments/171792.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/31/171792.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/171792.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/171792.html阅读全文

bacoo 2007-12-31 01:32 发表评论
]]>
[转蝲]使用Regex实现的ؓJFileChooser使用的FileFilter对象的创建类http://www.tkk7.com/bacoo/archive/2007/12/29/171617.htmlbacoobacooSat, 29 Dec 2007 12:39:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/29/171617.htmlhttp://www.tkk7.com/bacoo/comments/171617.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/29/171617.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/171617.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/171617.html阅读全文

bacoo 2007-12-29 20:39 发表评论
]]>
[改编]U程的用!http://www.tkk7.com/bacoo/archive/2007/12/28/171348.htmlbacoobacooFri, 28 Dec 2007 15:07:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/28/171348.htmlhttp://www.tkk7.com/bacoo/comments/171348.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/28/171348.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/171348.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/171348.html阅读全文

bacoo 2007-12-28 23:07 发表评论
]]>
有关byte转char、String的一些说?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/28/171345.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Fri, 28 Dec 2007 14:58:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/28/171345.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/171345.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/28/171345.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/171345.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/171345.html</trackback:ping><description><![CDATA[<p>package com.bacoo.www;</p> <p>import java.applet.*;<br /> import java.net.*;</p> <p>public class InetAddDemo extends Applet{<br />  public void test(){<br />   try{<br />    InetAddress add=InetAddress.getLocalHost();<br />    System.out.println(add.getHostAddress());<br />    System.out.println(add.getHostName());<br />    System.out.println(InetAddress.getLocalHost());<br />    System.out.println(add.hashCode());<br />    byte [] b= add.getAddress();<br />    <br />    /*ByteArrayInputStream bais=new ByteArrayInputStream(b);<br />    InputStreamReader isr=new InputStreamReader(bais);<br />    BufferedReader br=new BufferedReader(isr);<br />    char [] ch=new char[b.length];<br />    br.read(ch);<br />    System.out.println(ch);<br />    q段代码依然不能够打印出我们期望的结?/<br />    <br />    String s = "12345abcd";<br />    byte b2[] = s.getBytes();<br />    System.out.println(b2.toString());<br />    <br />    String s1="d?a?";<br />    byte [] s2=s1.getBytes();<br />    String s3=new String (s2);<br />    System.out.println(s3);<br />    String tt=new String(b);<br />    System.out.println(tt);<br />    System.out.println(Bytes2String(b));<br />    System.out.println(add.toString());<br />   }catch(Exception e){<br />    System.out.println(e.getMessage());<br />   }<br />  }<br />  <br />  public void init(){<br />   test();<br />  }<br />  <br />  public String Bytes2String(byte [] b){<br />   String str="";<br />   for(int i=0;i<b.length;i++){<br />    int t=(b[i]<<24)>>>24;<br />    str+=Integer.toString(t)+".";<br />   }<br />   str=str.substring(0, str.length()-1);<br />   return str;<br />  }<br /> }</p> <p>/*说明Q?br /> Q?Qjava中定义变量ƈ不需要赋予初始|pȝ自动为其?值或nullQ但是这仅限于在cM定义的属于类的类变量Q?br /> 而对于在cdC定义的(f)时变量,则必要赋初始|否则会出错的Q?br /> Q?Q位q算赋默认的两端都是int型变量,而且q回g是int型的。如果在位运符的两端有一个变量ؓlong型,则返回g为long型?br /> Q?Q对于bytecdQ比较特D,首先它是整型Q而且只有一个字节长度,而且是有W号的,q里需要特别说明的?br /> java中不会区分无W号和有W号Q既然byte是一个字节的有符hQ那它的表示范围是-128~127Q但是我们经怼把byte作ؓ<br /> 单字节的容器Q比如在文gdӞ或作为缓冲区旉是用byteq种cdQ如果要把byte转化为字W时׃有问题,<br /> 比如Q例如下面一个例?</p> <p> import java.io.UnsupportedEncodingException;</p> <p> public class test{<br />   public static void main(String g[]) {<br />    String s = "12345abcd";<br />    byte b[] = s.getBytes();<br />    String t = b.toString();</p> <p>   System.out.println(t);</p> <p>  }<br />  }<br />  输出字符串的l果和字W串s不一样了.<br />  q是因ؓ对于byte[]cdQ它也是Object的子c,但是数组q种Ҏ(gu)的子cdƈ没有特别的实现自qtoString()Ҏ(gu)Q因此我们调?br />  "b.toString()"后,实际上还是调用了Object父类里的toStringҎ(gu)<函数体内的具体代码是Q?br />  getClass().getName() + "@" + Integer.toHexString(hashCode())>Q该Ҏ(gu)只是q回了该cȝName+@+hashCode而已Q?br />  有意思的是,对于数组c,cd字是?["后紧跟数l的cdQ比如这里返回的是"[B"Q呵呵,挺有吧Q?/p> <p> l过以下方式转码可以正{换了:</p> <p> public class test{<br />   public static void main(String g[]) {<br />    String s = "12345abcd";<br />    byte b[] = s.getBytes();<br />    try {<br />     String t = new String(b);<br />     System.out.print(t);<br />    } catch (Exception e) {<br />     e.printStackTrace();<br />    }<br />   }<br />  }<br /> 因此如果只是单纯的用它来作Z个中转的用途,那就无所谓了Q但是一旦涉及到和字W的转化时就会有问题Q?br /> q里暂且用上q提到的Ҏ(gu)Q即重新构造一个String对象Q但是构造String对象有着如下的从byte[]<br /> 转化为Stringcd的潜规则Q?br /> 如果byte里存储的数据范围?~127Ӟ也就是字节的首位?Ӟ׃byte[]数组中的一个字节拿出来转化Z?br /> 两个字节的charcdQƈ把这个字W放到String中,如果范围?128~-1Ӟ也就是首位ؓ1Ӟ׃自动的把<br /> btye[]中下一个字节也拿出来,让这两个字节l合成一个两字节的charcdQ然后存攑ֈString中。从q里<br /> 也可以看Z个潜规则Q汉字表C成两字节的二进制时Q第一个字节肯定是负倹{?br /> 因此对于今天做的q个E序来说Q想要把保存在byte[]中的IP地址数值直接拿出来Q需要h为的把byte中存储的<br /> 有符h转化为无W号数据Q用单的位操作就可以实现了?br /> Q?Q还需要说明的一Ҏ(gu)Qjava中没有运符重蝲Q对于StringcL谓的+号可以连接字W串Q其实只是在~译器里面做了点手脚Q?br /> q不是真正意义上的运符重蝲?br /> Q?Q最后,q要说明的是Q要熟练的掌握String和各U数值类型之间的转化Ҏ(gu)Q?br /> 举int型和Stringcd转化的例子吧Q?br /> int b --> String strQ?br /> <1>str=""+b;<br /> <2>str=Integer.toString(b);//从int出发Q利用Integer包装cd?br /> <3>str=String.valueOf(b);//从str出发Q利用Stringcd?br /> String str --> int b;<br /> b=Integer.parseInt(str);<br /> b=Integer.parseInt(str, int radix); <br /> 最后,再对Integer.parseIntҎ(gu)作一点说明,str字符串只能ؓ三种形式之一Q即"[0-9]*"?-[0-9]*"<br /> ?\u002D[0-9]*"两种形式之一Q其中负?-'的ASCii码就是\u002DQ因此这两种形式是等L(fng)Q除此之?br /> 的Ş式均非法Q这里ؓ了写得简z,使用了正则表辑ּ的写法[0-9]*表示L长度数字序列?br /> */</p> <img src ="http://www.tkk7.com/bacoo/aggbug/171345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-28 22:58 <a href="http://www.tkk7.com/bacoo/archive/2007/12/28/171345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UDP通信的一个小例子Q?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/28/171320.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Fri, 28 Dec 2007 13:12:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/28/171320.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/171320.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/28/171320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/171320.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/171320.html</trackback:ping><description><![CDATA[<p>package com.bacoo.www;</p> <p>import java.io.IOException;<br /> import java.net.*;</p> <p>public class UDPServer implements Runnable{</p> <p> /**<br />   * @param args<br />   */<br />  <br />  public UDPServer(){<br />   new Thread(this).start();<br />   try{<br />    DatagramSocket dgs=new DatagramSocket(8765);<br />    byte [] buf=new byte[1024];<br />    DatagramPacket dgp=new DatagramPacket(buf,buf.length);<br />    <br />    for(int i=0;i<3;i++){<br />     dgs.receive(dgp);<br />     System.out.println("The server has received the datagram!");<br />     dgs.send(dgp);<br />    }<br />   }catch(IOException ioe){<br />    ioe.printStackTrace();<br />   }<br />  }<br />  public static void main(String[] args) {<br />   // TODO Auto-generated method stub<br />   new UDPServer();<br />  }</p> <p> public void run() {<br />   // TODO Auto-generated method stub<br />   new UDPClient();<br />  }</p> <p>}<br /> /*<br /> 说明Q?br /> q里要对UDP方式作一个简要的说明Q构成UDP通信机制的主要是两个c,即DatagramSocket和DatagramPacketQ?br /> 主要包括发送和接收两个斚w的内容,对于发送方来说Q需要:<br /> Q?Q徏立一个DatagramSocket对象Q注意徏立的时候不需要指定端口,因ؓ发送方x的是发送成功,而不在乎是从本机的哪个端口发送出ȝQ?br /> 而发送的具体事宜则是由DatagramPacket来完成的Q包括对目的地址的指定?br /> Q?Q徏立一个DatagramPacket对象Q注意要制定目的地址和对应的端口A?br /> Q?Q调用DatagramSocket对象的send函数发送,send函数的参数就是刚建立的DatagramPacket对象?br /> 对于接收Ҏ(gu)Ԍ需要:<br /> Q?Q徏立一个DatagramSocket对象Q注意要指定端口Q因Z为接收方Q不在乎接收的东西是从哪里来的,而只是在本机的一个指定端口进?br /> 接收ok了,但需要注意这里的端口要与发送方投递的端口A一致?br /> Q?Q徏立一个DatagramPacket对象Q注意不必指定地址和端口,因ؓq是被动的接Ӟ而在接收q程中,该DatagramPacket对象<br /> 扮演的角色仅仅是一个信息的承蝲者,也就是把从端口来的信息封存到它里面?br /> Q?Q调用DatagramSocket对象的receive函数接收Qreceive函数的参数就是刚建立的DatagramPacket对象?/p> <p>最后,q有一炚w要说明,是在刚刚指出的接受模式来说Q比如说本例中,虽然未给DatagramPacket对象指定地址和端口,但是<br /> 依然可以调用send函数q行发送,q是Z么呢Q因为它先调用了receive函数Q通过调用该函敎ͼ可以在接收过E中保存了信息的来源Q?br /> 也就是地址和端口,因此下次再用send发送时Q就仍然往q个地址和端口发送数据,因此可以发送成功?br /> */</p> <img src ="http://www.tkk7.com/bacoo/aggbug/171320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-28 21:12 <a href="http://www.tkk7.com/bacoo/archive/2007/12/28/171320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[改编]AWT和Swingl画http://www.tkk7.com/bacoo/archive/2007/12/28/171313.htmlbacoobacooFri, 28 Dec 2007 12:31:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/28/171313.htmlhttp://www.tkk7.com/bacoo/comments/171313.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/28/171313.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/171313.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/171313.html[改编]AWT和Swingl画
在AWT中,对于重量U组Ӟ在绘制时按照如下的调用进行:
1)因ؓpȝ触发而重l:Q说白了Q就是指q种重绘不是Zؓ的,不是我们自己写代码调用repaint(){函数进行重l,而是pȝ觉得有必要进行重l而进行的。)
a.《AWT》确定是一部分q是整个部g需要绘甅R?br /> b.《AWT》促使事件分zE调用部件的paint()Ҏ(gu)?br /> 2)因ؓE序触发而重l:Qh为在消息响应函数中或其他地方强制q行重绘的操作)
a.《程序》确定是一部分q是全部部g需要重M对应内部状态的改变?
b.《程序》调用部件的repaint()Q该Ҏ(gu)向《AWT》登C一个异步的h Q- 当前部g需要重甅R?
c.《AWT》促使事件分zE去调用部g的update() Ҏ(gu)?
d.如果部g没有覆盖(override)update()Ҏ(gu)Qupdate()的默认实C清除部g背景Q如果部件不?#8220;轻量U?#8221;Q,然后只是单地调用paint()Ҏ(gu)?br /> 说明Q不论是那种触发重绘的方式,均可以归l到paint()函数上来Q那Z么对于程序触发方式还要有个中间步?#8220;update()”呢?q是Z让我们能够通过重写update()Ҏ(gu)后,在里面进行我们想要的控制Q也是我们可以在这里做Ҏ(gu)章。当然我们也可以覆盖paint()函数Q但是有了update()函数之后Q我们就可以不干扰paint()Q让?#8220;全n?#8221;的负责绘Ӟ而在update()q个地方q行我们需要的控制。比如提到的只能用到重量U组件的“增量l制”Q就是首先由pȝ触发paintl制Q然后在q个基础上(也就是背景下Q,在鼠标左键的消息响应函数中调用repaintQ然后重写update函数Q只是让update函数Ld的内容,而不在update函数内部再调用paint函数了,q样避开了paint函数Q也是实现了所谓的“增量l制”。不q需要说明的是,增量l制只在一些特D的GUI部g上好用,比如我们下面l的q个例子Q就是刚用来描述“增量l制”的那个例子)中就是用的Canvasc,该类直接l承于Componentc,注意不是l承自Containerc,因ؓ在ContainercM又实C自己的paintҎ(gu)Q有了新的机Ӟq就和我们上q讲的这一大套ZComponentcȝpaintҎ(gu)不一致了?/p>

对于轻量U组Ӟ都是l承于ContainercȝQ?#8220;轻量U?#8221;部g需要一个处在容器体pM?#8220;重量U?#8221;部g提供q行l画的场所。当q个“重量U?#8221;?#8220;宗”被告知要l制自n的窗体时Q它必须把这个绘ȝh转化为对其所有子孙的l画h。这是由java.awt.Container的paint()Ҏ(gu)处理的,该方法调用包容于其内的所有可见的、ƈ且与l画区相交的轻量U部件的paint()Ҏ(gu)。因此对于所有覆盖了paint()Ҏ(gu)的Container子类Q?#8220;轻量U?#8221;?#8220;重量U?#8221;QContainer的子cM一定都是轻量lg哦,呵呵Q都需要在函数的最后调用父cȝpaintҎ(gu)Q即super.paint(g)?/p>

最后,对于AWTl制Q给Z下准则:
a.对于大多数程序,所有的客户区绘M码应该被攄在部件的paint()Ҏ(gu)中?
b.通过调用repaint()Ҏ(gu)Q程序可以触发一个将来执行的paint()调用Q不能直接调用paint()Ҏ(gu)?
c.对于界面复杂的部Ӟ应该触发带参数的repaint()Ҏ(gu)Q用参数定义实际需要更新的区域Q而不带参数调用会D整个部g被重甅R?
d.因ؓ对repaint()的调用会首先Dupdate()的调用,默认C促成paint()的调用,所以重量部g应该覆盖update()Ҏ(gu)以实现增量绘Ӟ如果需要的?轻量U部件不支持增量l制) ?
e.覆盖了paint()Ҏ(gu)的java.awt.Container子类应当在paint()Ҏ(gu)中调用super.paint()以保证子部g能被l制?
f.界面复杂的部件应该灵zd使用裁剪区来把绘画范围羃?yu)到只包括与裁剪区相交的范围?/p>

==============================================================================
Swingl画的处理过E?br />  Swing处理"repaint"h的方式与AWT有稍微地不同Q虽然对于应用开发h员来讲其本质是相同的 -- 同样是触发paint()。Swingq么做是Z支持它的RepaintManager API (后面介绍)Q就象改善绘L能一栗在Swing里的l画可以C条\Q如下所qͼ

(A) l画需求首先生于一个重量񔼜先(通常是JFrame、JDialog、JWindow或者JApplet)Q?br /> 1。事件分zE调用其先的paint()
2。Container.paint()的默认实C递归地调用Q何轻量子孙的paint()Ҏ(gu)?br /> 3。当到达W一个Swing部gӞJComponent.paint()的默认执行做下面的步骤:
 i.如果部g的双~冲属性ؓtrueq且部g的RepaintManager上的双缓冲已l激z,把Graphics对象转换Z个合适的屏外Graphics?
 ii.调用paintComponent()(如果使用双缓冲就把屏外Graphics传递进??
 iii.调用paintBorder()(如果使用双缓冲就把屏外Graphics传递进??br />  iv.调用paintChildren()(如果使用双缓冲就把屏外Graphics传递进?Q该Ҏ(gu)使用裁剪q且遮光和optimizedDrawingEnabled{属性来严密地判定要递归地调用哪些子孙的paint()?
 v.如果部g的双~冲属性ؓtrueq且在部件的RepaintManager上的双缓冲已l激z,使用最初的屏幕Graphics对象把屏外映像拷贝到部g上?/p>

 注意QJComponent.paint()步骤#1?5在对paint()的递归调用中被忽略?q里的JComponent指的是在paintChildren()函数中判断出的需要递归调用的组Ӟ在步?4中介l了)Q因为所有在swingH体层次中的轻量U部件将׃n同一个用于双~冲的屏外映像?


(B) l画需求从一个javax.swing.JCponent扩展cȝrepaint()调用上生:
1。JComponent.repaint()注册一个针寚w件的RepaintManager的异步的重画需求,该操作用invokeLater()把一个Runnable加入事g队列以便E后执行在事件分zE上的需求?
 
2。该Runnable在事件分zE上执行q且D部g的RepaintManager调用该部件上paintImmediately()Q该Ҏ(gu)执行下列步骤Q?/p>

 i.使用裁剪框以及遮光和optimizedDrawingEnabled属性确?#8220;?#8221;部gQ绘M定从q个部g开?处理透明以及潜在的重q部??
 ii.如果栚w件的双缓冲属性ؓtrueQƈ且根部g的RepaintManager上的双缓冲已Ȁz,{换Graphics对象到适当的屏外Graphics?
 iii.调用栚w?该部件执行上q?A)中的JComponent.paint()步骤#2-4)上的paint()Q导致根部g之下的、与裁剪框相交的所有部件被l制?
 iv.如果栚w件的doubleBuffered属性ؓtrueq且栚w件的RepaintManager上的双缓冲已l激z,使用原始的Graphics把屏外映像拷贝到部g?/p>

 注意Q如果在重画没有完成之前Q又有发生多起对部g或者Q何一个其先的repaint()调用Q所有这些调用会被折q到一个单一的调用,卛_到最上层Q这里的层指的是那种HierarchyQ而不是展现给我们的最上面的那个图或者按钮)的SWing部g的paintImmediately()Q调用它的repaint()。例如,如果一个JTabbedPane包含了一个JTableq且在其包容层次中的现有的重画需求完成之前两ơ发布对repaint()的调用,其结果将变成对该JTabbedPane部g的paintImmediately()Ҏ(gu)的单一调用Q会触发两个部g的paint()的执行?br />  
q意味着对于Swing部g来说Qupdate()不再被调用?

虽然repaint()Ҏ(gu)D了对paintImmediately()的调用,它不考虑"回调"l图Qƈ且客L(fng)的绘M码也不会攄到paintImmediately()Ҏ(gu)里面。实际上Q除非有Ҏ(gu)的原因,Ҏ(gu)不需要超载paintImmediately()Ҏ(gu)?

===================================================================================
Swingl画准则
Swing开发h员在写绘M码时应该理解下面的准则:
1。对于Swing部gQ不是pȝQ触发还是程序-触发的请求,M调用paint()Ҏ(gu)Q而update()不再被Swing部g调用?
 
2。程序可以通过repaint()触发一个异步的paint()调用Q但是不能直接调用paint()?
 
3。对于复杂的界面Q应该调用带参数的repaint()Q这样可以仅仅更新由该参数定义的区域Q而不要调用无参数的repaint()Q导致整个部仉甅R?
 
4。Swing中实现paint()?个要素是调用3个分ȝ回调Ҏ(gu)Q?br />  paintComponent()
 paintBorder()
 paintChildren()
 Swing部g的子c,如果x行自ql画代码Q应该把自己的绘M码放在paintComponent()Ҏ(gu)的范围之内?不要攑֜paint()里面)?
 
5。Swing引进了两个属性来最大化的改善绘ȝ性能|?
 opaque: 部g是否要重d所占据范围中的所有像素位Q?
 optimizedDrawingEnabled: 是否有这个部件的子孙与之交PQ?
 
6。如果Swing部g?遮光)opaque属性设|ؓtrueQ那pC它要负责绘制它所占据的范围内的所有像素位(包括在paintComponent()中清除它自己的背?Q否则会造成屏幕垃圾?
7。如果一个部件的遮光?opaque)和optimizedDrawingEnabled属性有一个被讄为falseQ将D在每个绘L作中要执行更多的处理Q因此我们推荐的明智的方法是同时使用透明q且交P部g?
8。用UI代理(包括JPanel)的Swing部g的扩展类的典型作法是在它们自qpaintComponent()的实C调用super.paintComponent()。因为UI代理可以负责清除一个遮光部件的背景Q不q这一操作需要根据规?5中的讑֮来决定?br /> 9。Swing通过JComponent的doubleBuffered属性支持内|的双缓Ԍ所有的Swing部g该属性默认值是trueQ然而把Swing容器的遮光设|ؓtrue有一个整体的构思,把该容器上的所有轻量子孙的属性打开Q不它们各自的讑֮?
10。强烈徏议ؓ所有的Swing部g使用双缓册Ӏ?
11。界面复杂的部g应该灉|地运用剪切框来,只对那些与剪切框怺的区域进行绘L作,从而减工作量?


P.S.英文出处Qhttp://java.sun.com/products/jfc/tsc/articles/painting/index.html



bacoo 2007-12-28 20:31 发表评论
]]>
[转蝲]Java反射机制http://www.tkk7.com/bacoo/archive/2007/12/21/169450.htmlbacoobacooFri, 21 Dec 2007 13:50:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/21/169450.htmlhttp://www.tkk7.com/bacoo/comments/169450.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/21/169450.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169450.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169450.html阅读全文

bacoo 2007-12-21 21:50 发表评论
]]>
JTree学习(fn)W记Q?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/21/169445.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Fri, 21 Dec 2007 12:56:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/21/169445.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169445.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/21/169445.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169445.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169445.html</trackback:ping><description><![CDATA[<p>对于JTree比较重要的几个类或接口:<br /> 1。TreeMode是一个接口,是构建树(wi)的模型,接口中比较重要的几个函数是:getChild、getChildCount、getRoot、getIndexOfChild、isLeaf。如果想把一些特D的东西抽象成一|(wi)Q那么就可以实现该接口,用自己构造的q个模型来创建树(wi)JTree(TreeModel newModel) <br /> 2。TreeNode是一个接口,代表?wi)的节点。DefaultMutableTreeNode是该接口的一个实玎ͼ可以直接用来创徏?wi)的节点?br /> 3。TreePath是一个类Q负责节点到根的路径<br /> 4。TreeSelectionModel是一个接口,表示?wi)选择lg的当前状态。DefaultTreeSelectionModelcL该接口的一个实现类?/p> <p> <table cellspacing="0" cellpadding="3" width="100%" summary="" border="1"> <tbody> <tr class="TableHeadingColor" bgcolor="#ccccff"> <th align="left" colspan="2"><font size="+2"><strong>构造方法摘?/strong></font></th> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree()">JTree</a></strong>()</code> <br />           q回带有CZ模型?<code>JTree</code>?/td> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree(java.util.Hashtable)">JTree</a></strong>(<a title="java.util 中的c? href="file:///D:/Program%20Files/Java/api/java/util/Hashtable.html">Hashtable</a><?,?> value)</code> <br />           q回?<code>Hashtable</code> 创徏?<code>JTree</code>Q它不显C根?/td> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree(java.lang.Object[])">JTree</a></strong>(<a title="java.lang 中的c? href="file:///D:/Program%20Files/Java/api/java/lang/Object.html">Object</a>[] value)</code> <br />           q回 <code>JTree</code>Q指定数l的每个元素作ؓ不被昄的新根节点的子节炏V?/td> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree(javax.swing.tree.TreeModel)">JTree</a></strong>(<a title="javax.swing.tree 中的接口" href="file:///D:/Program%20Files/Java/api/javax/swing/tree/TreeModel.html">TreeModel</a> newModel)</code> <br />           q回 <code>JTree</code> 的一个实例,它显C根节点 - 使用指定的数据模型创建树(wi)?/td> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree(javax.swing.tree.TreeNode)">JTree</a></strong>(<a title="javax.swing.tree 中的接口" href="file:///D:/Program%20Files/Java/api/javax/swing/tree/TreeNode.html">TreeNode</a> root)</code> <br />           q回 <code>JTree</code>Q指定的 <code>TreeNode</code> 作ؓ其根Q它昄根节炏V?/td> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree(javax.swing.tree.TreeNode, boolean)">JTree</a></strong>(<a title="javax.swing.tree 中的接口" href="file:///D:/Program%20Files/Java/api/javax/swing/tree/TreeNode.html">TreeNode</a> root, boolean asksAllowsChildren)</code> <br />           q回 <code>JTree</code>Q指定的 <code>TreeNode</code> 作ؓ其根Q它用指定的方式昄根节点,q确定节Ҏ(gu)否ؓ叶节炏V?/td> </tr> <tr class="TableRowColor" bgcolor="white"> <td><code><strong><a href="file:///D:/Program%20Files/Java/api/javax/swing/JTree.html#JTree(java.util.Vector)">JTree</a></strong>(<a title="java.util 中的c? href="file:///D:/Program%20Files/Java/api/java/util/Vector.html">Vector</a><?> value)</code> <br />           q回 <code>JTree</code>Q指?<code>Vector</code> 的每个元素作Z被显C的新根节点的子节点?/td> </tr> </tbody> </table> </p> <p>常用Ҏ(gu)Q?br /> 1。得到模型:<br /> getModel()?DefaultTreeModel)getModel()<br /> 2。得到根Q?br /> getModel().getRoot()?DefaultMutableTreeNode)getModel().getRoot()<br /> 3。根据node得到pathQ?br /> TreePath visiblePath = new TreePath(((DefaultTreeModel)getModel()).getPathToRoot(node))<br /> 4。根据Path展开到该节点Q?br /> makeVisible(visiblePath)<br /> 5。根据path讑֮该节炚w定<br /> tree.setSelectionPath(visiblePath)<br /> 6。滚动到可见位置Q?br /> scrollRowToVisible(int row)<br /> 7。展开?lt;从根展开或从某一个节点展开><br /> 关于JTree的展开<br />    // If expand is true, expands all nodes in the tree.<br />    // Otherwise, collapses all nodes in the tree.<br />  public static void expandAll(JTree tree, boolean expand) {<br />   TreeNode root = (TreeNode) tree.getModel().getRoot();</p> <p>  // Traverse tree from root<br />   expandAll(tree, new TreePath(root), expand);<br />  }</p> <p> private static void expandAll(JTree tree, TreePath parent, boolean expand) {<br />   // Traverse children<br />   TreeNode node = (TreeNode) parent.getLastPathComponent();<br />   if (node.getChildCount() >= 0) {<br />    for (Enumeration e = node.children(); e.hasMoreElements();) {<br />     TreeNode n = (TreeNode) e.nextElement();<br />     TreePath path = parent.pathByAddingChild(n);<br />     expandAll(tree, path, expand);<br />    }<br />   }</p> <p>  // Expansion or collapse must be done bottom-up<br />   if (expand) {<br />    tree.expandPath(parent);<br />   } else {<br />    tree.collapsePath(parent);<br />   }<br />  }<br /> 8。遍历树(wi)的所有节?lt;从根遍历或从某一个节炚w?gt;<br /> public static void visitAllNodes(JTree tree) {<br />   TreeNode root = (TreeNode) tree.getModel().getRoot();<br />   visitAllNodes(tree,root);<br />  }</p> <p> public static void visitAllNodes(JTree tree,TreeNode node) {<br />   // node is visited exactly once<br />   //you can do your things about this node,such as:<br />   tree.makeVisible(new TreePath(<br />     ((DefaultTreeModel)tree.getModel()).getPathToRoot(node)));</p> <p>  if (node.getChildCount() >= 0) {<br />    for (Enumeration e = node.children(); e.hasMoreElements();) {<br />     TreeNode n = (TreeNode) e.nextElement();<br />     visitAllNodes(tree,n);<br />    }<br />   }<br />  }<br /> 9。遍历树(wi)已经展开的节?lt;从根遍历或从某一个节炚w?gt;<br /> // Traverse all expanded nodes in tree<br />  public static void visitAllExpandedNodes(JTree tree) {<br />   TreeNode root = (TreeNode) tree.getModel().getRoot();<br />   visitAllExpandedNodes(tree, new TreePath(root));<br />  }</p> <p> public static void visitAllExpandedNodes(JTree tree, TreePath parent) {<br />   // Return if node is not expanded<br />   if (!tree.isVisible(parent)) {<br />    return;<br />   }</p> <p>  // node is visible and is visited exactly once<br />   TreeNode node = (TreeNode) parent.getLastPathComponent();<br />   //you can do your things about this node,such as:<br />   System.out.println(node.toString());</p> <p>  // Visit all children<br />   if (node.getChildCount() >= 0) {<br />    for (Enumeration e = node.children(); e.hasMoreElements();) {<br />     TreeNode n = (TreeNode) e.nextElement();<br />     TreePath path = parent.pathByAddingChild(n);<br />     visitAllExpandedNodes(tree, path);<br />    }<br />   }<br />  }</p> <p>一个较为完整的l习(fn)Q?br /> import java.awt.Dimension;<br /> import java.awt.Color;<br /> import java.awt.event.MouseAdapter;<br /> import java.awt.event.MouseEvent;<br /> import java.util.Enumeration;<br /> import javax.swing.JFrame;<br /> import javax.swing.JPanel;<br /> import javax.swing.JScrollPane;<br /> import javax.swing.JTree;<br /> import javax.swing.BoxLayout;<br /> import javax.swing.tree.DefaultMutableTreeNode;<br /> import javax.swing.tree.DefaultTreeModel;<br /> import javax.swing.tree.TreeNode;<br /> import javax.swing.tree.TreePath;</p> <p>public class JTreeDemo {</p> <p> public static void expandAll(JTree tree, boolean expand) {<br />   TreeNode root = (TreeNode) tree.getModel().getRoot();</p> <p>  // Traverse tree from root<br />   expandAll(tree, new TreePath(root), expand);<br />  }</p> <p> private static void expandAll(JTree tree, TreePath parent, boolean expand) {<br />   // Traverse children<br />   TreeNode node = (TreeNode) parent.getLastPathComponent();<br />   if (node.getChildCount() >= 0) {<br />    for (Enumeration e = node.children(); e.hasMoreElements();) {<br />     TreeNode n = (TreeNode) e.nextElement();<br />     TreePath path = parent.pathByAddingChild(n);<br />     expandAll(tree, path, expand);<br />    }<br />   }</p> <p>  // Expansion or collapse must be done bottom-up<br />   if (expand) {<br />    tree.expandPath(parent);<br />   } else {<br />    tree.collapsePath(parent);<br />   }<br />  }</p> <p> <br />  public static void visitAllNodes(JTree tree) {<br />   TreeNode root = (TreeNode) tree.getModel().getRoot();<br />   visitAllNodes(tree,root);<br />  }</p> <p> public static void visitAllNodes(JTree tree,TreeNode node) {<br />   // node is visited exactly once<br />   //you can do your things about this node,such as:<br />   tree.makeVisible(new TreePath(<br />     ((DefaultTreeModel)tree.getModel()).getPathToRoot(node)));</p> <p>  if (node.getChildCount() >= 0) {<br />    for (Enumeration e = node.children(); e.hasMoreElements();) {<br />     TreeNode n = (TreeNode) e.nextElement();<br />     visitAllNodes(tree,n);<br />    }<br />   }<br />  }</p> <p> // Traverse all expanded nodes in tree<br />  public static void visitAllExpandedNodes(JTree tree) {<br />   TreeNode root = (TreeNode) tree.getModel().getRoot();<br />   visitAllExpandedNodes(tree, new TreePath(root));<br />  }</p> <p> public static void visitAllExpandedNodes(JTree tree, TreePath parent) {<br />   // Return if node is not expanded<br />   if (!tree.isVisible(parent)) {<br />    return;<br />   }</p> <p>  // node is visible and is visited exactly once<br />   TreeNode node = (TreeNode) parent.getLastPathComponent();<br />   //you can do your things about this node,such as:<br />   System.out.println(node.toString());</p> <p>  // Visit all children<br />   if (node.getChildCount() >= 0) {<br />    for (Enumeration e = node.children(); e.hasMoreElements();) {<br />     TreeNode n = (TreeNode) e.nextElement();<br />     TreePath path = parent.pathByAddingChild(n);<br />     visitAllExpandedNodes(tree, path);<br />    }<br />   }<br />  }<br />  public static JTree tr;<br />  public static void main(String[] args) {</p> <p>  // 构造函敎ͼJTree()<br />   JTree example1 = new JTree();<br />   tr=example1;<br />   example1.setBackground(Color.lightGray);<br />   example1.addMouseListener(new MouseAdapter(){<br />    public void mouseClicked(MouseEvent me){<br />     try{<br />      visitAllNodes(tr);<br />      Thread.sleep(2000);<br />      System.out.println(tr.getPathForRow(1).toString());<br />      expandAll(tr,tr.getPathForRow(1),false);<br />      Thread.sleep(2000);<br />      visitAllExpandedNodes(tr);<br />     }catch(InterruptedException e){<br />      e.printStackTrace();<br />     }<br />    }<br />   });</p> <p>  // 构造函敎ͼJTree(Object[] value)<br />   Object[] letters = { " a ", " b ", " c ", " d ", " e " };<br />   JTree example2 = new JTree(letters);</p> <p>  // 构造函敎ͼJTree(TreeNode root)(TreeNodeI?<br />   // 用空l点创徏?br />   DefaultMutableTreeNode node1 = new DefaultMutableTreeNode(); // 定义?wi)结?br />   JTree example3 = new JTree(node1); // 用此?wi)结点做参数调?JTree的构造函数创建含有一个根l点的树(wi)</p> <p>  // 构造函敎ͼJTree(TreeNode root)(同上,只是TreeNode非空)<br />   // 用一个根l点创徏?br />   DefaultMutableTreeNode node2 = new DefaultMutableTreeNode(" Color ");<br />   JTree example4 = new JTree(node2); // l点不可以颜?默认为白面黑?br />   example4.setBackground(Color.lightGray);</p> <p>  // 构造函敎ͼJTree(TreeNode root, boolean<br />   // asksAllowsChildren)(同上,只是TreeNode又有不同)<br />   // 使用DefaultMutableTreeNodecd用一个根l点创徏?wi),讄为可d孩子l点,再添加孩子结?br />   DefaultMutableTreeNode color = new DefaultMutableTreeNode(" Color ",<br />     true);<br />   DefaultMutableTreeNode gray = new DefaultMutableTreeNode(" Gray ");<br />   color.add(gray);<br />   color.add(new DefaultMutableTreeNode(" Red "));<br />   gray.add(new DefaultMutableTreeNode(" Lightgray "));<br />   gray.add(new DefaultMutableTreeNode(" Darkgray "));<br />   color.add(new DefaultMutableTreeNode(" Green "));<br />   JTree example5 = new JTree(color);</p> <p>  // 构造函敎ͼJTree(TreeNode root)(同上,只是TreeNode非空)<br />   // 通过逐个dl点创徏?br />   DefaultMutableTreeNode biology = new DefaultMutableTreeNode(" Biology ");<br />   DefaultMutableTreeNode animal = new DefaultMutableTreeNode(" Animal ");<br />   DefaultMutableTreeNode mammal = new DefaultMutableTreeNode(" Mammal ");<br />   DefaultMutableTreeNode horse = new DefaultMutableTreeNode(" Horse ");<br />   mammal.add(horse);<br />   animal.add(mammal);<br />   biology.add(animal);<br />   JTree example6 = new JTree(biology);<br />   horse.isLeaf();<br />   horse.isRoot();</p> <p>  // 构造函?JTree(TreeModel newModel)<br />   // 用DefaultMutableTreeNodelcd义一个结点再用这个结点做参数定义一个用DefaultTreeMode<br />   // 创徏一个树(wi)的模?再用JTree的构造函数创Z个树(wi)</p> <p>  DefaultMutableTreeNode root = new DefaultMutableTreeNode(" Root1 ");<br />   DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(" Child1 ");<br />   DefaultMutableTreeNode child11 = new DefaultMutableTreeNode(" Child11 ");<br />   DefaultMutableTreeNode child111 = new DefaultMutableTreeNode(<br />     " Child111 ");<br />   root.add(child1);<br />   child1.add(child11);<br />   child11.add(child111);</p> <p>  DefaultTreeModel model = new DefaultTreeModel(root);</p> <p>  JTree example7 = new JTree(model);</p> <p>  JPanel panel = new JPanel();<br />   panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));<br />   panel.setPreferredSize(new Dimension(700, 400));<br />   panel.add(new JScrollPane(example1)); // JTree必须攑֜JScrollPane?br />   panel.add(new JScrollPane(example2));<br />   panel.add(new JScrollPane(example3));<br />   panel.add(new JScrollPane(example4));<br />   panel.add(new JScrollPane(example5));<br />   panel.add(new JScrollPane(example6));<br />   panel.add(new JScrollPane(example7));</p> <p>  JFrame frame = new JFrame(" JTreeDemo ");<br />   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />   frame.setContentPane(panel);<br />   frame.pack();<br />   frame.setVisible(true);<br />  }<br /> }</p> <p>另外一个例子,在该例子中笔者用基于本机目录构建的模型来构建树(wi)Q?br /> </p> <p>/** <br />  * 查API时发?.4FileSystemViewq个东东多了一些功? <br />  * 无聊地写了这个文件目录树(wi) <br />  * <br />  * 声明Q用j2sdk1.4 <br />  * :实现自己的Filec,以过滤掉一般文Ӟ只剩下目?<br />  * ~点Qgui慢得要死,swing的通病?(my pc==256ddr,thunderbird900,xp) <br />  */</p> <p>import java.awt.Component;<br /> import java.io.*;<br /> import javax.swing.*;<br /> import javax.swing.event.TreeModelListener;<br /> import javax.swing.filechooser.FileSystemView;<br /> import javax.swing.tree.*;</p> <p>public class Test {</p> <p> /** <br />   * javax.swing.filechooser.FileSystemView在这个程序里很重要, <br />   * 用法参考j2sdk1.4 API文 <br />   * 切记Q?.4 not 1.3!!!!!!!! <br />   */<br />  private static FileSystemView fileView;<br />  int a=BB;<br />  static int BB=34;</p> <p> /** <br />   *在这里用了Singleton模式 <br />   * 不过g没什么破?<br />   */<br />  static FileSystemView getFileView() {<br />   if (fileView == null)<br />    fileView = FileSystemView.getFileSystemView();<br />   return fileView;<br />  }<br />   <br />  public static void main(String[] args) throws Exception {<br />   //如果加入下面q句,会ؕ?i wonder why <br />   UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); </p> <p>  //initial frame <br />   JFrame frame = new JFrame();<br />   frame.setSize(400, 300);<br />   //关闭H口旉出程?<br />   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);</p> <p>  //initial tree with customer TreeModel <br />   <br />   JTree tree = new JTree(new CustomTreeModel());</p> <p>  //set customer TreeCellRenderer <br />   tree.setCellRenderer(new CustomTreeCellRenderer());<br />   frame.getContentPane().add(new JScrollPane(tree));<br />   frame.setVisible(true);<br />  }<br /> }</p> <p>class CustomTreeModel implements TreeModel {<br />  private FileSystemView fileView;</p> <p> public CustomTreeModel() {<br />   fileView = Test.getFileView();<br />  }</p> <p> //q回根节?<br />  public Object getRoot() {<br />   return fileView.getRoots()[0];<br />  }</p> <p> //q回父节点parent的第index个子节点,index?开?<br />  public Object getChild(Object _parent, int index) {<br />   File parent = (File) _parent;<br />   return parent.listFiles()[index];<br />  }</p> <p> //q回父节点parent?子节点child的位|?与上面的Ҏ(gu)正好相反 <br />  public int getIndexOfChild(Object parent, Object child) {<br />   File[] files = ((File) parent).listFiles();<br />   for (int i = 0; i < files.length; i++) {<br />    if (files[i].equals(child))<br />     return i;<br />   }<br />   return -1;<br />  }</p> <p> //q回父节点parent的子节点?<br />  public int getChildCount(Object parent) {<br />   File[] files = ((File) parent).listFiles();<br />   /** <br />    *maybe driver not ready,ie cdrom <br />    *then files is null <br />    */<br />   if (files == null)<br />    return -1;</p> <p>  return files.length;<br />  }</p> <p> //是否叶节?<br />  public boolean isLeaf(Object node) {<br />   return ((File) node).isFile();<br />  }</p> <p> public void valueForPathChanged(TreePath path, Object newValue) {<br />  }</p> <p> /** <br />   *下面的方法要实现,则要涉及比较复杂的事件处?<br />   *如果有兴? <br />   *可以单的使用javax.swing.EventListenerList来实?<br />   */<br />  public void addTreeModelListener(TreeModelListener l) {<br />  }</p> <p> public void removeTreeModelListener(TreeModelListener l) {<br />  }</p> <p>}</p> <p>/** <br />  * 如果没有安装自己的CellRenderer <br />  * JTree默认的CellRenderer是JLabel <br />  * 它只是简单的setText(node.toString) <br />  * CustomeTreeCellRenderer也只是简单取?<br />  * windows默认的文件图标和文g?装到JLabel上去 <br />  */</p> <p>class CustomTreeCellRenderer extends DefaultTreeCellRenderer {<br />  /**<br />   * <br />   */<br />  private static final long serialVersionUID = 3892593039200536416L;<br />  private FileSystemView fileView;</p> <p> public CustomTreeCellRenderer() {<br />   fileView = Test.getFileView();<br />  }</p> <p> public Component getTreeCellRendererComponent(JTree tree, Object value,<br />    boolean selected, boolean expanded, boolean leaf, int row,<br />    boolean hasFocus) {<br />   super.getTreeCellRendererComponent(tree, value, selected, expanded,<br />     leaf, row, hasFocus);<br />   File file = (File) value;<br />   setIcon(fileView.getSystemIcon(file));<br />   setText(fileView.getSystemDisplayName(file));<br />   return this;<br />  }<br /> }</p> <img src ="http://www.tkk7.com/bacoo/aggbug/169445.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-21 20:56 <a href="http://www.tkk7.com/bacoo/archive/2007/12/21/169445.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jdbc的一些事儿!http://www.tkk7.com/bacoo/archive/2007/12/20/169194.htmlbacoobacooThu, 20 Dec 2007 15:48:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169194.htmlhttp://www.tkk7.com/bacoo/comments/169194.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169194.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169194.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169194.html数据库分Zc,一cL可以自己本地理的,例如Access、FoxBase{;另一cL供PC机通过服务器访问的数据库,例如Oracle、MS SQL Server{大型数据库。ؓ了让数据库提供给用户l一的GUI和APIQ生了标准ODBC?

 

JDBC是一个通用的底层的、支持基本SQL功能的Java API。它提供了两部分与数据库独立的APIQ即JDBC API和JDBC Driver API?

 

JavaE序通过JDBC API讉KJDBC Driver ManagerQJDBC Driver Manager再通过JDBC Driver API 讉K不同的JDBC驱动E序Q从而实现对不同数据库的讉K。说白了是底层是数据库Q上层是用户的访问请求,中间层包括各个数据库的各自的驱动E序、用戯用的API函数Q只不过q里的API有两个子层,中间加入了一个JDBC Driver Manager来进行管理。整个链是这L(fng)QDB--〉DB Driver--〉JDBC Driver API--〉JDBC Driver Manager--〉JDBC API--〉用?

 

JDBC URLl构Q?

jdbc:<子协?gt;:<子名U?gt;

例如Q?

jdbc:odbc:test

Tips:

(1)

如果通过|络来访问数据库Q则网l地址的放在子名称部分Q格式ؓQ?/hostname:port/sub protocol

例如Q?

jdbc:dbnet://ant:356/fred

(2)

对于odbc子协议,比较Ҏ(gu)Q可以在子名U后面接L多个属性值的特征。因此odbc子协议的完整语法为:

jdbc:odbc:<数据源名U?gt;[;<属性名>=<属性?gt;;......]

例如Q?

jdbc:odbc:mydb;UID=bacoo;PWD=bacoo



bacoo 2007-12-20 23:48 发表评论
]]>
JDBC的那些事儿!Q?Q?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/20/169193.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Thu, 20 Dec 2007 15:47:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/20/169193.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169193.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/20/169193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169193.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169193.html</trackback:ping><description><![CDATA[<h1>q接数据?/h1> <p>所有与数据库有关的对象和方法都?java.sql 包中Q因此在使用 JDBC 的程序中必须加入 <tt>"import java.sql.* "</tt>?JDBC 要连?ODBC 数据库,(zhn)必首先加?JDBC-ODBC 桥驱动程? <pre>Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");</pre> <p>该语句加载驱动程序,q创cȝ一个实例。然后,要连接一个特定的数据库,(zhn)必d?Connect cȝ一个实例,q?URL 语法q接数据库? <pre>String url = "jdbc:odbc:Grocery prices";</pre> <pre>Connection con = DriverManager.getConnection(url);</pre> <p>h意,(zhn)用的数据库名是?zhn)?ODBC 讄面板中输入的“数据?#8221;名称? <p>URL 语法可能因数据库cd的不同而变化极大? <pre>jdbc:<em>subprotocol</em>:<em>subname</em></pre> <p>W一l字W代表连?em>协议</em>Qƈ且始l是 <tt>jdbc</tt>。还可能有一?em>子协?/em>Q在此处Q子协议被指定ؓ <tt>odbc</tt>。它规定了一cL据库的连通性机制。如果?zhn)要连接其它机器上的数据库服务器,可能也要指定该机器和一个子目录Q? <pre>jdbc:bark//doggie/elliott</pre> <p>最后,(zhn)可能要指定用户名和口oQ作接字W串的一部分Q? <pre>jdbc:bark//doggie/elliot;UID=GoodDog;PWD=woof</pre> <pre>*******************************************************************************************</pre> <pre>*******************************************************************************************</pre> <p>上面l出了连接数据库的一U方法,其实q有另外一U方法,如下Q? <p>System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver"); <p>String url = "jdbc:odbc:Grocery prices"; <p>Connection con=DriverManager.getConnection(url); <p>说明Q? <p>我们可以用System.getProperty("jdbc.drivers")对设定的System属性D行查询。其实,对于System属性,pȝ认可的属性如下: <p>java.version            Java Runtime Environment version<br /> java.vendor            Java Runtime Environment vendor<br /> java.vendor.url            Java vendor URL<br /> java.home            Java installation directory<br /> java.vm.specification.version                    Java Virtual Machine specification version<br /> java.vm.specification.vendor                    Java Virtual Machine specification vendor<br /> java.vm.specification.name                    Java Virtual Machine specification name<br /> java.vm.version            Java Virtual Machine implementation version<br /> java.vm.vendor            Java Virtual Machine implementation vendor<br /> java.vm.name            Java Virtual Machine implementation name<br /> java.specification.version                Java Runtime Environment specification version<br /> java.specification.vendor             Java Runtime Environment specification vendor<br /> java.specification.name        Java Runtime Environment specification name<br /> java.class.version                        Java class format version number<br /> java.class.path                  Java class path<br /> java.library.path                        List of paths to search when loading libraries<br /> java.io.tmpdir                Default temp file path<br /> java.compiler            Name of JIT compiler to use<br /> java.ext.dirs            Path of extension directory or directories<br /> os.name                Operating system name<br /> os.arch                Operating system architecture<br /> os.version            Operating system version<br /> file.separator            File separator ("/" on UNIX)<br /> path.separator            Path separator (":" on UNIX)<br /> line.separator            Line separator ("\n" on UNIX)<br /> user.name            User's account name<br /> user.home            User's home directory<br /> user.dir                            User's current working directory <p>大家可以看到其中q没有jdbc.driversq一个属性,但是System的属性可以随意的由我们来dQ比如我们用setProperty讑֮了一个名?#8220;bacoo”的属性,q指定该属性gؓ“test”的话Q那么当我们用getProperty时就可以索到属性bacoo的gؓtest。这里之所以要加入“jdbc.drivers”q个属性|是因为DriverManagerq个c默认的会在初始化时去System中搜索这一属性的|在这个属性g我们可以多个需要加载的驱动用冒?#8220;:”隔开Q又׃DriverManager是一个静态类Q其实在定义一个类Ӟ不允许用static修饰Q只允许public、final、abstract三个修饰W,q里说其是静态类指的是该cȝ所有方法和属?lt;其实该类也没有属性,q构造函数都没有>均是静态的Q,因此在调用DriverManager.getConnection(url)ӞDriverManager需要先初始化,׃加蝲驱动了? <h1>讉K数据?/h1> <p>一旦连接到数据库,可以请求表名以及表列的名称和内容等信息Q而且(zhn)可以运?SQL 语句来查询数据库或者添加或修改其内宏V可用来从数据库中获取信息的对象有: <h3><strong><u>DatabaseMetaData</u></strong></h3> <p>有关整个数据库的信息Q表名、表的烦引、数据库产品的名U和版本、数据库支持的操作? <p>DatabaseMetaData dbmd; <p>dbmd=con.getMetaData(); <p>下面重点介绍一下DatabaseMetaDat中的两个重要函数getTables和getColumnsQ? <p><code><a >ResultSet</a> </code><code><strong><a href="http://bacoox.spaces.live.com/java/sql/DatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])"><font color="#ff0000">getTables</font></a></strong>(<a >String</a> catalog, <a >String</a> schemaPattern, <a >String</a> tableNamePattern, <a >String</a>[] types)</code> <p>仅返回与目录、模式、表名称和(表)cd标准匚w的表描述? <pre>catalogQ要在其中查找表名的目录名。对?JDBC-ODBC 数据库以及许多其他数据库而言Q可其讄?<tt>null</tt>。这些数据库的目录项实际上是它在文gpȝ中的l对路径名称?/pre> <pre>schemaPatternQ要包括的数据库“Ҏ(gu)”。许多数据库不支持方案,而对另一些数据库而言Q它代表数据库所有者的用户名。一般将它设|ؓ <tt>null</tt>?/pre> <pre>tableNamePatternQ一个掩码,用来描述(zhn)要索的表的名称。如果?zhn)希望索所有表名,则将其设为通配W?<tt>%</tt>?em>h意,</em><em>SQL 中的通配W是<strong> </strong><strong>%</strong> W号Q而不是一?PC 用户?* W号?/em></pre> <pre>types[]Q这是描q?zhn)要检索的表的cd?String 数组。数据库中通常包括许多用于内部处理的表Q而对作ؓ用户的?zhn)没什么h(hun)倹{如果它是空|则?zhn)会得到所有这些表。如果?zhn)其设ؓ包含字符?#8220;<tt>TABLES</tt>”的单元素数组Q?zhn)仅获得对用h用的表格?/pre> <p><strong>例子Q?/strong> <p>String [] types=new String[1];<br /> types[0]="TABLE"; <p>rs=dbmd.getTables(null, null, "%", types); <p>Java Doc中说该函数返回的表描qC息都包括以下10U信息,TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKS、TYPE_CAT、TYPE_SCHEM、TYPE_NAME、SELF_REFERENCING_COL_NAME、REF_GENERATIONQ但是在实际试Ӟq回的结果中只有TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKSq?V顺便要说一声的是,变量types可以取的值有Q?TABLE"?VIEW"?SYSTEM TABLE"?GLOBAL TEMPORARY"?LOCAL TEMPORARY"?ALIAS" ?"SYNONYM"Q通常只取TABLE? <p>************************************************************************************************************************************************************************************************* <p><code><a >ResultSet</a> </code><code><strong><a href="http://bacoox.spaces.live.com/java/sql/DatabaseMetaData.html#getColumns(java.lang.String, java.lang.String, java.lang.String, java.lang.String)"><font color="#ff0000">getColumns</font></a></strong>(<a >String</a> catalog, <a >String</a> schemaPattern, <a >String</a> tableNamePattern, <a >String</a> columnNamePattern)</code> <p>仅返回与目录、模式、表和列名称标准匚w的列描述? <p>通常在得到有x定表Q比如我们这里指定了表名为FoodPriceQ的列的描述信息的结果集QrsQ之后,我们重点兛_的是<strong>COLUMN_NAME</strong>?strong>DATA_TYPEQ数据类型占用的字节敎ͼ比如整型是4Q?/strong>?strong>TYPE_NAMEQINTEGER、CURRENCY之类的类型名UͼQ?/strong>当然最兛_的肯定是COLUMN_NAME了。下面把l果集中所有可以得到的信息列给出如下: <p>TABLE_CAT、TABLE_SCHEM、TABLE_NAME、COLUMN_NAME、DATA_TYPE、TYPE_NAME、COLUMN_SIZE、BUFFER_LENGTH、DECIMAL_DIGITS、NUM_PREC_RADIX、NULLABLE、REMARKS、COLUMN_DEF、SQL_DATA_TYPE、SQL_DATETIME_SUB、CHAR_OCTET_LENGTH、ORDINAL_POSITION、IS_NULLABLE、ORDINAL? <p>例子Q? <p>rs=dbmd.getColumns(null, null, "FoodPrice", null); <p>因此我们通常? <p>while(rs.next()){<br />                 System.out.print(rs.getString("COLUMN_NAME")+"\t");<br /> }来得到该表中所有的列名U?strong>其实q就是一个从l果集中索的l果</strong>? <p>  <h3><strong><u>ResultSet</u></strong></h3> <p>关于某个表的信息或一个查询的l果。?zhn)必须逐行讉K数据行,但是(zhn)可以Q何顺序访问列? <p>对于数据库中表的描述信息的结果集可以q样得到Qrs=dbmd.getTables(null, null, "%", null); <p>对于某张表中的列的描qC息的l果集可以这样得刎ͼrs=dbmd.getColumns(null, null, "FoodPrice", null); <p>对于要从表中索具体的W合要求的结果集Q而不仅仅是一些描qC息了Q就必须使用如下的方法: <p>Statement st=con.createStatement(); <p>String query="SELECT FoodName FROM FOOD;";//注意字符串中要包?#8220;;”Q?br /> rs=st.executeQuery(query); <p>  <h3><strong><u>ResultSetMetaData</u></strong></h3> <p>有关 ResultSet 中列的名U和cd的信息? <p>ResultSetMetaData rsmd; <p>rsmd = rs.getMetaData(); <p>numCols = rsmd.getColumnCount(); <p>// 打印列名<br /> for (i = 1; i <= numCols; i++) <blockquote> <p>System.out.print(rsmd.getColumnName(i) + "     ");</p> </blockquote> <p>System.out.println(); <p>  <p>最后,l出一些零散的知识Q? <p>Q?Q对于数据库的连接、访问等{操作都需要放在try和catch块中q行Q都有可能抛出SQLException异常Q用该异常c需要import java.sql.*; <p>Q?Q前面提到的DatabaseMetaDat、ResultSet、ResultSetMetaData均是接口Q而不是类Q在下面的例子中Q通过跟踪调试Q可以发现在E序q行q程中生的都是ZJdbcOdbc驱动的类Q即JdbcOdbcResultSet{类Q把q些c(它们都实C相应的接口)实例化后赋值给ResultSet接口Q如ResultSet rs=dbmd.getColumns(null, null, "FoodPrice", null);因此Q我们们不难推断出对于其他类型的数据库驱动,均是q样一个原理,同时也理解了Z么Java中有许多接口Q而ƈ没有与这些接口对应的实现了它们的c,再一ơ验证了接口是一U标准,一U规范? <p>l出一个完整的例子Q? <p>package com.bacoo.www; <p>import java.sql.*;<br /> public class JdbcOdbcTest { <p>    ResultSet rs;<br />     ResultSetMetaData rsmd;<br />     DatabaseMetaData dbmd;<br />     Connection con;<br />     int numCols,i;<br />     public JdbcOdbcTest(){<br />         System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver");<br />         String url="jdbc:odbc:Groceries";<br />         String query="SELECT DISTINCTROW FoodName FROM Food " +<br />                 "WHERE (FoodName like 'C%');";<br />         try{<br />             //Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");<br />             con=DriverManager.getConnection(url);<br />             dbmd=con.getMetaData();<br />             System.out.println("Connected to:"+dbmd.getURL());<br />             System.out.println("Driver "+ dbmd.getDriverName());<br />             String [] types=new String[1];<br />             types[0]="TABLE";<br />             rs=dbmd.getTables(null, null, "%", null);<br />             dumpResults("--Tables--");<br />             rs.close();<br />         }catch(Exception e){<br />             System.out.println(e);<br />         }<br />         System.out.println("--Column Names--");<br />         try{<br />             rs=dbmd.getColumns(null, null, "FoodPrice", null);<br />             while(rs.next()){<br />                 System.out.print(rs.getString("COLUMN_NAME")+" ");<br />             }<br />             System.out.println();<br />             rs.close();<br />         }catch(Exception e){<br />             System.out.println(e);<br />         }<br />         try{<br />             Statement st=con.createStatement();<br />             rs=st.executeQuery("SELECT FoodName FROM FOOD;");<br />         }catch(Exception e){<br />             System.out.println("query exception");<br />         }        <br />         dumpResults("--contents of FoodName column--");<br />         try{<br />             Statement st=con.createStatement();<br />             rs=st.executeQuery(query);<br />         }catch(Exception e){<br />             System.out.println("query exception");<br />         }<br />         dumpResults("--Results of Query--");<br />     } <p>    private void dumpResults(String head) {<br />         // q是打印列标头和每列的内容的<br />         // 通用Ҏ(gu)<br />         System.out.println(head);<br />         try {<br />             // 从元数据中获取列?br />             rsmd = rs.getMetaData();<br />             numCols = rsmd.getColumnCount();<br />             // 打印列名<br />             for (i = 1; i <= numCols; i++)<br />                 System.out.print(rsmd.getColumnName(i) + "?);<br />             System.out.println();<br />             // 打印列内?br />             while (rs.next()) {<br />                 for (i = 1; i <= numCols; i++)<br />                     System.out.print(rs.getString(i) + "\t");<br />                 System.out.println();<br />             }<br />         } catch (Exception e) {<br />             System.out.println(e.getMessage());<br />         }<br />     } <p>    public static void main(String[] args) {<br />         // TODO Auto-generated method stub<br />         new JdbcOdbcTest();<br />         System.out.println(System.getProperty("jdbc.drivers"));<br />     } <p>} <p>  <p>q行的结果是Q? <p>Connected to:jdbc:odbc:Groceries<br /> Driver JDBC-ODBC Bridge (odbcjt32.dll)<br /> --Tables--<br /> TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKS?br /> C:\Documents and Settings\Administrator\桌面\db1    null    MSysAccessObjects    SYSTEM TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    MSysAccessXML    SYSTEM TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    MSysACEs    SYSTEM TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    MSysObjects    SYSTEM TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    MSysQueries    SYSTEM TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    MSysRelationships    SYSTEM TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    Food    TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    FoodPrice    TABLE    null    <br /> C:\Documents and Settings\Administrator\桌面\db1    null    Stores    TABLE    null    <br /> --Column Names--<br /> FSKey StoreKey FoodKey Price <br /> --contents of FoodName column--<br /> FoodName?br /> Apples    <br /> Oranges    <br /> Hamburger    <br /> Butter    <br /> Milk    <br /> Coca Cola    <br /> Green beans    <br /> --Results of Query--<br /> FoodName?br /> Coca Cola    <br /> sun.jdbc.odbc.JdbcOdbcDriver <p>当然使用该例子,必须要先建立一个数据源?/p> <img src ="http://www.tkk7.com/bacoo/aggbug/169193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-20 23:47 <a href="http://www.tkk7.com/bacoo/archive/2007/12/20/169193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javapȝ属?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/20/169191.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Thu, 20 Dec 2007 15:46:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/20/169191.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169191.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/20/169191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169191.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169191.html</trackback:ping><description><![CDATA[<div>1.  java.runtime.name:java的运行环境名U?<br /> 2.  sun.boot.library.path:jdk\jre中的bin的\?<br /> 3.  java.vm.version:虚拟机的版本?<br /> 4.  java.vm.vendor:java虚拟机的发行?<br /> 5.  java.vendor.url:java发行者的|络地址 <br /> 6.  path.separator:路径分隔W,ؓ”;” <br /> 7.  java.vm.name:虚拟机名?<br /> 8.  file.encoding.pkg=”sun.io” <br /> 9.  sun.java.launcher:java的发行版?<br /> 10.  user.country:用户的国?<br /> 11.  sun.os.patch.level:操作pȝ的版本号 <br /> 12.  java.vm.specification.name:虚拟机的规则说明文档的名?<br /> 13.  user.dirQ用戯\径(window 下ؓ”c:\”Q?<br /> 14.  java.runtime.version:jdk的版本号 <br /> 15.  java.awt.graphicsenv:awt的图形环境(window下ؓQ(”sun.awt.Win32GraphicsEnvironment”Q) <br /> 16.  java.endorsed.dirs:java{注文g的\?<br /> 17.  os.arch:操作pȝ支持的cpu型号 <br /> 18.  java.io.tmpdir:io操作的(f)时文件\?<br /> 19.  line.separator:换行W?<br /> 20.  java.vm.specification.vendor:虚拟则说明文的发行?<br /> 21.  user.variant:用户变量 <br /> 22.  os.name:操作pȝ的名U?<br /> 23.  sun.jnu.encoding:”GBK” <br /> 24.  java.library.path:库的路径jdk\bin……即path的内?<br /> 25.  java.specification.name:java的规则说明文的名称 <br /> 26.  java.class.version: <br /> 27.  sun.management.compiler:”HotSpot Client Compiler” <br /> 28.  os.version: <br /> 29.  user.home:用户文g的\?<br /> 30.  user.timezon:时区 <br /> 31.  java.awt.printerjob:”sun.awt.windows.WprinterJob” <br /> 32.  file.encoding:文g~码”GBK” <br /> 33.  java.specification.version:java规则?<br /> 34.  java.class.path:classpath <br /> 35.  user.name:用户?<br /> 36.  java.vm.specificaton.version:虚拟机的版本 <br /> 37.  java.home:”C:\java\jdk\jre” <br /> 38.  sun.arch.data.model:cpu数据位数 <br /> 39.  user.language:”zh” <br /> 40.  java.specification.vendor:java的发行?<br /> 41.  awt.toolkit:”sun.awt.windows.WToolkit” <br /> 42.  java.vm.info:”mixed mode, sharing” <br /> 43.  java.version:jdk版本 <br /> 44.  java.ext.dirs:ext的\?<br /> 45.  sun.boot.class.path:cL件的path <br /> 46.  java.vendorQjava的发行?<br /> 47.  file.separator:文g分隔W?<br /> 48.  java.vendor.url.bug:java发行者的urlhttp://java.sun.com/cgi-bin/bugreport.cgi <br /> 49.  sun.io.unicode.encoding:”UnicodeLittle” <br /> 50.  sun.cpu.endian:”little” <br /> 51.  sun.desktop:”windows”,所在的环境 <br /> 52.  sun.cpu.isalist:”Pentium_pro+mmx Pentium_pro pentium+mmx Pentium i486 i386 i86”</div> <div> </div> <div>如果惌己测试一下本机器内的所有系l属性,可以使用如下的代码:</div> <div> <p>import java.util.Iterator;<br /> import java.util.Properties; <p>public class sysEnv {<br />  <br />  public static void main(String args[])<br />  {<br />   Properties props=System.getProperties();<br />   Iterator iter=props.keySet().iterator();<br />   while(iter.hasNext())<br />   {<br />   String key=(String)iter.next();<br />   System.out.println(key+" = "+ props.get(key));<br />   }<br />  }<br /> }<br /> </p> </div> <img src ="http://www.tkk7.com/bacoo/aggbug/169191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-20 23:46 <a href="http://www.tkk7.com/bacoo/archive/2007/12/20/169191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转蝲]J2DK 1.5?.6 & 中文版APIQ全Q?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/20/169188.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Thu, 20 Dec 2007 15:45:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/20/169188.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169188.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/20/169188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169188.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169188.html</trackback:ping><description><![CDATA[<div> <div> <a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div>        <font color="#008000">Sun 公司提供的Java API Docs是学?fn)和使用Java语言中最l常使用的参考资料之一。但是长期以来此文档只有英文版,对于中国地区的Java开发者来说相当的不便。目前Sun 公司正在l织多方力量此文译成中文,q于2005q?0?1日在Sun 中国技术社区(<a target="_blank"><u><font color="#800080">http://gceclub.sun.com.cn/</font></u></a>Q?正式发布W一批中文版Java API文Q包括java.lang和java.utilcdAPI 文档的中文版Q。经q将q?0个月的努力,目前我们已经Java SE 5.0的全部API文档中文化。开发h员可以通过Sun 中国技术社区的|站在线览相关文Q也可以全部文下载到本地以方便检索和使用?/font><a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div> <a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div><font size="2"><font color="#ff1493"><strong><font color="#0000ff">J2SE DK & API下蝲</font></strong><br /> </font>-------------------------<br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/j2se/1.3/download.html</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/j2se/1.4.2/download.html</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/javase/downloads/index_jdk5.jsp</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/javase/downloads/index.jsp</u></font></a></font><a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div> <a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div><font size="2"><strong><font color="#0000ff">J2EE DK & API下蝲</font></strong>  <br /> -------------------------<br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/j2ee/1.3/index.jsp</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/j2ee/1.3/download.html</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/j2ee/1.4/index.jsp</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/j2ee/1.4/download.html</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/javaee/downloads/index.jsp</u></font></a></font><a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div> <a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div><font size="2"><strong><font color="#0000ff">JDK1.6API中文版(全)</font></strong><br /> -------------------------<br /> * HTML 格式(在线英文) <a target="_blank"><u><font color="#0000ff">http://java.sun.com/javase/6/docs/</font></u></a><br /> * HTML 格式(在线中文) <a target="_blank"><u><font color="#800080">http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/index.html</font></u></a><br /> * zip 格式(中文) <a target="_blank"><u><font color="#800080">http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html_zh_CN.zip</font></u></a><br /> * CHM 格式(中文)  <a target="_blank"><font color="#0000ff"><u>http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/chm/JDK_API_1_6_zh_CN.CHM</u></font></a><br /> </font><a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div><font size="2"><strong></strong></font> <a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div><font size="2"><strong><font color="#0000ff">JDK1.5API中文版(全)</font></strong><br /> -------------------------<br /> * HTML 格式(在线英文) <a target="_blank"><u><font color="#0000ff">http://java.sun.com/javase/5/docs/</font></u></a><br /> * HTML 格式(在线中文)  <a target="_blank"><u><font color="#800080">http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/index.html</font></u></a><br /> * zip 格式(中文) <a target="_blank"><u><font color="#0000ff">http://gceclub.sun.com.cn/Java_Docs/html_zh_CN.zip</font></u></a><br /> * CHM 格式(中文) <a target="_blank"><font color="#0000ff"><u>http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/builds/JDK_API_1_5_zh_CN.CHM</u></font></a><br /> </font><a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div> <a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> <div><font size="2"><strong><font color="#0000ff">相关|站<br /> </font></strong>-------------------------<br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com</u></font></a><br /> <a target="_blank"><u><font color="#0000ff">http://gceclub.sun.com.cn/</font></u></a><br /> <a target="_blank"><font color="#0000ff"><u>http://developers.sun.com/downloads/</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/javaee/downloads/</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://java.sun.com/javase/downloads/</u></font></a><br /> <a target="_blank"><font color="#0000ff"><u>http://www.netbeans.info/downloads/</u></font></a></font></div> <div><font size="2"><a ><u><font color="#0000ff">http://java.sun.com/docs/books/tutorial/index.html</font></u></a><br /> </font><a ><u><font color="#0000ff">leizhimin 51cto技术博?/font></u></a></div> </div> <img src ="http://www.tkk7.com/bacoo/aggbug/169188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-20 23:45 <a href="http://www.tkk7.com/bacoo/archive/2007/12/20/169188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中窗体的创徏Q?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/20/169190.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Thu, 20 Dec 2007 15:45:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/20/169190.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169190.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/20/169190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169190.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169190.html</trackback:ping><description><![CDATA[<div>一般来Ԍ在java中要完成一个Frame或者JFrame的显C,需要以下步骤,通常都将ȝ(定义为public的类)l承于Frame或者JPanel?br /> Q一Q如果是l承自FrameQ则Q?br /> 讄标题QsetTitle("Your Title");<br /> 讄大小QsetSize(int width,int height)或者pack()<br /> 使窗口显C:setVisible(true)<br /> 使窗口居中显C:setLocationRelativeTo(null)<br /> 使窗口的关闭动作有效Q?br /> addWindowListener(new WindowAdapter(){<br /> public void windowClosing(WindowEvent e){<br /> System.exit(0);<br /> }<br /> });<br /> Q二Q如果是l承自JPanelQ则Q?br /> 讄标题QsetTitle("Your Title");<br /> 讄外观QJFrame.setDefaultLookAndFeelDecorated(true);</div> <div>得到内容面板的内容:JComponent jc=new ȝ?);</div> <div>讄内容不透明Qjc.setOpaque(true);<br /> 讄内容面板QsetContentPane(jc);<br /> 讄大小QsetSize(int width,int height)或者pack()<br /> 使窗口显C:setVisible(true)<br /> 使窗口居中显C:setLocationRelativeTo(null)<br /> 使窗口的关闭动作有效QsetDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)Q?/div> <div>此外Q还有另外一个设|窗口大的函数是setPreferredSize(new Dimension(int width,int height))Q但是调用该函数后必d调用pack()函数才行。而且Q该函数比setSize函数的优先高,如果同时讄了setPreferredSize和setSize两个函数Q那么setSize函数不发挥作用?/div> <img src ="http://www.tkk7.com/bacoo/aggbug/169190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-20 23:45 <a href="http://www.tkk7.com/bacoo/archive/2007/12/20/169190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JTabbedPane遇到的问题!http://www.tkk7.com/bacoo/archive/2007/12/20/169187.htmlbacoobacooThu, 20 Dec 2007 15:44:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169187.htmlhttp://www.tkk7.com/bacoo/comments/169187.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169187.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169187.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169187.html对于JTabbedPaneQ其实用h很简单,
1。创?br /> 2。调用addTab(String title, Component component)//q里的component一般是用JPanel
但是在同一个容器中Q不允许把同一个panel攑֜JTabbedPane中后再接着add到容器中来,比如我们在JTabbedPane中放|了panel1和panel2Q然后又把panel1d到容器中了,则实际显C的效果为JTabbedPane中只有panel2一个属性页Q因为panel1已经在容器中了,q一点容易被忽略Q请注意?br />

其实Q不光是JTabbedPane有这U问题,M一个组仉不能在同一个容器(或面板)中被加蝲两次Q不Z何种方式?/p>

bacoo 2007-12-20 23:44 发表评论
]]>
JScrollPane的简单用法!http://www.tkk7.com/bacoo/archive/2007/12/20/169186.htmlbacoobacooThu, 20 Dec 2007 15:42:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169186.htmlhttp://www.tkk7.com/bacoo/comments/169186.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169186.html#Feedback1http://www.tkk7.com/bacoo/comments/commentRss/169186.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169186.html1。定义实例:JScrollPane jsp=new JScrollPane(某个l承自JPanelcȝ实例 pane);
2。设|初始大:jsp.setPreferredSize(new Dimension(200,200));
3。在适当的时候(已经判断出jsp容纳不下里面的内Ҏ(gu)Q重新设|大:jsp.setPreferredSize(一个新的Dimension);
4。调用jsp.revalidate();
5。调用jsp.repaint();
Tips:
有一个JScrollPane的成员函数是scrollRectToVisible(Rectangle rect)Q该成员函数能够使某一块rect在当前的滚动面板内可见,x动面板能够通过滚动来得需要显C的区域Q由rect界定出的那块区域Q被昄?/div>

bacoo 2007-12-20 23:42 发表评论
]]>
[转蝲]JavaҎ(gu)的发明v因及代码应用实例http://www.tkk7.com/bacoo/archive/2007/12/20/169185.htmlbacoobacooThu, 20 Dec 2007 15:39:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169185.htmlhttp://www.tkk7.com/bacoo/comments/169185.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169185.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169185.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169185.html
        Ҏ(gu)能够消除h代码Q让源代码的可读性更高,q能提供U别更高的错误检查。从EJB3到JUnit4Q哪里都在用它。本文就告诉你如何使用它?br />   Java 5向Java引入了批?Annotations)Q它的用迅速成为现代Java开发中不可~少的一部分。在正式开始介l它之前Q看看ؓ什么要发明Ҏ(gu)Q这是非常值得的?br />   自从Java诞生之日PZ׃直在解决它初期忽视了的一些问题:~少元数据;~ZJava以外的代码嵌入到Java源代码文仉的能力等。当 Java面市的时候,针对q些问题而推出的JavaDocl于让它变完整了。JavaDoc使用了在代码里专门标记注释的概念Q从而让它能够提取出额外的信息,说具体点是文档Qƈ它转换成ؓ我们熟?zhn)的JavaDoc文档。这是一简单的技术,Zh都可以用。首先会有DocletQ目的是让h们扩展文档的输出。然后是XdocletQ它像用标C样用JavaDoc来生成代码,从而将整个q程变得轻而易举。这部分是对J2EE的复杂性的回应?J2EE原来依靠很多h代码(boilerplate code)把对象捆l到J2EE框架里。但是这些方案都有一些问题。首先,注释里的标记从来都不会进入最l的源代码,所以除非你生成代码来反映这些标讎ͼ否则你无法在q行期间查找到它。其ơ,它会把整个预处理层加?在理x况下应该?一个简单编译过E里。最后,Z注释的标记在~译期间q不是很Ҏ(gu)查,也无法轻易被很多IDE查;如果你把注释标记拼写错了Q编译器是不会注意到的,~译器只会关注那些它知道切名字的标记?br />   要解册所有的问题QJava新增了批注。批注是用于Java语言的本机元数据标记。它们的输入严格与Java语言的其他部分类|可以通过反映被发玎ͼ更容易地?IDE和编译器的编写者管理。现在就让我们看一些被Ҏ(gu)的代码吧Q我们先从BaseExample开始,它是一个简单类Q只带有一个方法—?myMethodQ?/div>

  public class BaseExample {

  public BaseExample() {}

  public void myMethod() {

  System.out.println("This is the BaseExample");

  }

  }

  现在Q我们想要扩展BaseExampleq替代myMethod。下面就是完成这一d的Example1代码Q?br />
  public class Example1 extends BaseExample {

  public Example1() {}

  @Overridepublic void myMethod() {

  System.out.println("This is the Example1");

  }

  }

  q样我们有了第一个关于myMethod的批?a href="mailto:——@Override">——@Override。这是一pd内置的批注之一。@Override的意思是“Ҏ(gu)必须替代其超cM的一个方法;如果做不到这一点,那么׃有东西出错,使得~译器生错?#8221;。没有@OverrideQ代码照样会正常工作Q但是假设有Z改BaseExampleQ让myMethod带有参数。如果你没有使用@OverrideҎ(gu)Q代码仍然会被编译,隐藏了子cL有替代超cL法的问题。如果有@Override的话Q你会在~译期间看到发生错误?br />   你可能会认ؓ“N语言的扩展没有解册个问题,额外的关键字可能会吗”Q是的,它可能已l实Cq一点,但是q不仅没有给语言带来M灉|性,q会D很多源代码兼Ҏ(gu)的问题。批注这U方式避免了改变Java语言本n(当然除了增加了@markup)Qƈ且还能够攑֜代码的不同部分里Q而不仅仅是在标记Ҏ(gu)里?br />   关于Ҏ(gu)q有一Ҏ(gu)Q你可以创徏自己的批注标讎ͼq正是我们马上要讨论的内宏V想一想下面这个问题:我们有一些简单的Java BeansE序Q它们都带有不同的字W串字段。我们希望能够有一些通用H体昄代码Q它们能够用其他昄提示(比如宽度)来正地标示q些字段。现在我们可以编写一个超c,它能够提取出q个数据Q比如说从一个在每个c里都带有一些静态支持方法的静态数l里Q但是这也意味着要强制给代码分层。利用批注做到这一点就要简单得多了。现在让我们从定义FormLabel.java里的FormLabel的批注开始:

  import java.lang.annotation.*;

  @Retention(RetentionPolicy.RUNTIME)

  @Target(ElementType.METHOD)

  public@interface FormLabel {String label();

  int width() default 40;

  }

  你应该注意到的第一件事是Java使用了它自己内置的一些批注来定批注:@Retention和@Target。@Retention用来定义通过讄 RetentionPolicy的值批注能够在构徏-q行q程中存留多久。这里我们用了RUNTIMEQ这意味着我们定义的批注将会在q行期间被保留在代码里。RetentionPolicy.SOURCE被用于一个我们希望被~译器用然后抛弃的Ҏ(gu)。RetentionPolicy.CLASS让它们保留在生成的类文g里,但是能够在运行期间被Java虚拟?JVM)讉K到?br />   在默认情况下Q你可以在代码里的Q何地斚w应用Ҏ(gu)?@TargetҎ(gu)让你能够它限制在代码的特定部分里。在本文里,我们把目标瞄准了ElementType.METHODQ这意味着它只能够与方法关联在一赗其他ElementTypes有CONSTRUCTOR、FIELD、LOCAL_VARIABLE、PACKAGE、PARAMETER?TYPEQ每个都能够把批注限制到该种cd的Java语言元素Q所以例如,讄TYPE只允许Ҏ(gu)为定义过的这U类型,比如Q?br />
  @OurAnnotation

  public class OurAnnotatedClass {…

  值得注意的是Q@TargetҎ(gu)能够接受单个ElementType或者一个ElementType数组Q如果你惌批注限制ؓ一pd语言元素的话?br />   下面一部分是批注接口的定义Q这像是一个普通的接口声明Q除了我们用@interface其标记Z个批注。在q个接口里,我们然后定义Ҏ(gu)的方法,像我们希望用在与批注相兌的信息上的抽象方法,所以我们就有了String label()Q用于一个叫做label的字W串属性。如果我们没有方法,那么Ҏ(gu)只能用?#8220;做标?#8221;Q而@Overrides注释是q样一个例子。如果你只有一个属性,它最好被命名?#8220;value”Q因为当带有一个未命名参数的批注在讄q个值时Q它工作得最好。属性还可以有默认|比如“int width() default 40;”是在定义一个默认gؓ40的整数属性?br />   q就是批注定义。我们现在就可以在代码里使用它了。下面一个SimpleDatacd用到了它?br />
  public class SimpleData {

  private String firstname;

  private String lastname;

  private String postcode;

  public SimpleData() {}

  @FormLabel(label="First Name")

  public String getFirstname() { return firstname; }

  public void

  setFirstname(String firstname) {this.firstname = firstname;}

  @FormLabel(label="Last Name",width=80)

  public String getLastname() { return lastname; }

  public void setLastname(String lastname) {

  this.lastname = lastname;

  }

  @FormLabel(label="Postal code",width=10)

  public String getPostcode() { return postcode; }

  public void setPostcode(String postcode) {

  this.postcode = postcode;

  }

  }

  当然Q如果我们不查找Ҏ(gu)Q那么它们对代码的执行就不会造成M不同。我们所需要的是在q行期间使用Ҏ(gu)的方式;我们通过Reflection API来达到这一目的。现在就让我们创Z个简单的processFormҎ(gu)Q它能够在Q何对象里查找Ҏ(gu)?br />
  public void processForm(Object o) {

  for(Method m:o.getClass().getMethods()) {

  我们在传递给Ҏ(gu)的对象的c里定义所有的Ҏ(gu)。现在,我们需要检查每个方法,看看它们是否有FormLabelҎ(gu)Q以及是否返回一个String(Z单地说明问题Q我们给所有的l果多返回一些代?Q?br />
  if(m.isAnnotationPresent(FormLabel.class) &&

  m.getReturnType()==String.class) {

  现在我们可以通过使用Method的getAnnotation()Ҏ(gu)来提取FormLabelҎ(gu)Q?br />
  FormLabel formLabel=

  m.getAnnotation(FormLabel.class);

  现在我们执行Ҏ(gu)来取得其字符串|q过在批注接口里定义的方法访问批注属性。下面我们就把它们打印出来:

  try {

  String value=(String)m.invoke(o);

  String label=formLabel.label();

  int width=formLabel.width();

  System.out.printf("%s[%d]:%s\n",label,width,value);

  } catch (IllegalArgumentException ex) {

  ex.printStackTrace();

  }

  catch (IllegalAccessException ex) {

  ex.printStackTrace();}

  catch (InvocationTargetException ex) {

  ex.printStackTrace();

  }

  }

  }

  }

  现在我们可以创徏含有@FormLabelҎ(gu)的新c,q把它们传递给processFormҎ(gu)。这是在q行期间讉K你自qҎ(gu)的基?br />   现在q个时候,我们回头看看Java 5里面其他关于Ҏ(gu)的内宏V首先是~译器指令——@Deprecated?a>@SuppressWarnings。@Deprecated是把Ҏ(gu)标示否定的增强方法;不推荐把它用在新代码里,以防止以后删除。用@Deprecated可以生成一个来自编译器的相兌告?br />
  @SuppressWarnings会阻止编译器在封闭代码元素里警告你,所以你可以在类定义的开始或者对特定的方法?strong style="color: black; background-color: rgb(255,255,102)">@SuppressWarnings。它可以带参敎ͼ用来指定需要取消的错误的类型,例如Q?br />
  @SuppressWarnings("unchecked")

  public List getList() {

  List l=new LinkedList();

  return l;

  }

  q里我们取消了一个关于在List和List之间?#8220;未检?#8221;的强制{换。当你开始用Java~程但是没有非一般代码的时候,q就非常有用。在取消警告的时候,可能地~小取消的范围是值得的;在上面的例子里,我们取消了整个代码。我们可以把它变紧凑Q只隐藏一个语句的错误Q?br />
  public List

  getListToo() {

  @SuppressWarnings("unchecked")

  List l=new LinkedList();

  return l;

  }

  要注意的是,你需要在Java2SE 1.5.06或者以上的版本上进行这工作;q之前的版本没有提供对@SuppressWarning支持?br />   Java 5里其他内|的Ҏ(gu)都与Ҏ(gu)注的支持有关——@Documented和@Inherited。它们都可以被加到批注定义里。@Documented的作用是Q批注的使用应该在所有生成的JavaDoc文里都反映出来。正如你可能看到的,Ҏ(gu)和JavaDoc标记是互补的。@Inherited的意思是Q当另外一个类用类来扩展批注时Q批注应该是可承的Q在默认情况下,Ҏ(gu)是不能被l承的?br />
  你可能很希望在自q开发项目里使用JavaҎ(gu)的方法。就像我在引a里讲到的Q批注已l成为现代Java框架和应用程序的重要一部分Q就?JUnit4举个例子QJavaҎ(gu)已经允许JUnit的开发h员有了以更丰富的方式表示试的方法,而不用要求测试编写者强制用统一的命名规则。还?GrailsQ这里批注可以被用来?#8220;cM铁轨(rails-like)”的框架提供信息。批注的能力有很多,但是要记住,能力大Q责M大。批注是Zl开发h员提供标C息,而不是用来隐藏运行配|?/div>
 
完整的Java代码例子Q?/font>
 
package com.shou.www;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface FormLabel {
 String label();
 int width() default 40;
}
public class AnnotationDemo {
 private String firstname="Zhao";
 private String lastname="Bacoo";
 private String postcode="116023";
 public AnnotationDemo() {
 }
 @FormLabel(label = "First Name")
 public String getFirstname() {
  return firstname;
 }
 public void setFirstname(String firstname) {
  this.firstname = firstname;
 }
 @FormLabel(label = "Last Name", width = 80)
 public String getLastname() {
  return lastname;
 }
 public void setLastname(String lastname) {
  this.lastname = lastname;
 }
 @FormLabel(label = "Postal code", width = 10)
 public String getPostcode() {
  return postcode;
 }
 public void setPostcode(String postcode) {
  this.postcode = postcode;
 }
 public void processForm(Object o) {
  for (Method m : o.getClass().getMethods()) {
   if (m.isAnnotationPresent(FormLabel.class) &&
   m.getReturnType() == String.class) {
    FormLabel formLabel = m.getAnnotation(FormLabel.class);
    try {
     String value = (String) m.invoke(o);
     String label = formLabel.label();
     int width = formLabel.width();
     System.out.printf("%s[%d]:%s\n", label, width, value);
    } catch (IllegalArgumentException ex) {
     ex.printStackTrace();
    }
    catch (IllegalAccessException ex) {
     ex.printStackTrace();
    }
    catch (InvocationTargetException ex) {
     ex.printStackTrace();
    }
   }
  }
 }
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  AnnotationDemo ad=new AnnotationDemo();
  ad.processForm(ad);
 }
 
}
//E序q行的结果如下:
//First Name[40]:Zhao
//Last Name[80]:Bacoo
//Postal code[10]:116023
最后,在IBM的网站上q有译q来的两不错的关于java注释斚w的讲解,但是那两文章比较基本,不如上面q篇文章q样l典和深刻,有兴的读者可以参考:
http://www.ibm.com/developerworks/cn/java/j-annotate1/
http://www.ibm.com/developerworks/cn/java/j-annotate2.html


bacoo 2007-12-20 23:39 发表评论
]]>[转蝲]java设计模式之Bridge(抽象和行为分开)http://www.tkk7.com/bacoo/archive/2007/12/20/169184.htmlbacoobacooThu, 20 Dec 2007 15:38:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169184.htmlhttp://www.tkk7.com/bacoo/comments/169184.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169184.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169184.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169184.htmlBridge定义 :
  抽象和行ؓ划分开?各自独立,但能动态的l合.
  
  Z么?
  通常,当一个抽象类或接口有多个具体实现(concrete subclass),q些concrete之间关系可能有以下两U?
  1. q多个具体实C间恰好是q列?如前面D?打桩,有两个concrete class:方Ş桩和圆Ş?q两个Ş状上的桩是ƈ列的,没有概念上的重复,那么我们只要使用l承可以了.
  
  2.实际应用?常常有可能在q多个concrete class之间有概念上重叠.那么需要我们把抽象共同部分和行为共同部分各自独立开?原来是准备放在一个接口里,现在需要设计两个接?分别攄抽象和行?
  
  例如,一杯咖啡ؓ?有中杯和大杯之分,同时q有加奶 不加奶之? 如果用单U的l承,q四个具体实?中杯 大杯 加奶 不加?之间有概念重?因ؓ有中杯加?也有中杯不加? 如果再在中杯q一层再实现两个l承,很显然؜?扩展性极?那我们用Bridge模式来实现它.
  
  如何实现?
  以上面提到的咖啡 Z. 我们原来打算只设计一个接?抽象c?,使用Bridge模式?我们需要将抽象和行为分开,加奶和不加奶属于行ؓ,我们它们抽象成一个专门的行ؓ接口.
  
  先看看抽象部分的接口代码:
  
  public abstract class Coffee
  {
    CoffeeImp coffeeImp;
  
    public void setCoffeeImp() {
      this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();
    }
  
    public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}
  
    public abstract void pourCoffee();
  }
  
  其中CoffeeImp 是加不加奶的行ؓ接口,看其代码如下:
  
  public abstract class CoffeeImp
  {
    public abstract void pourCoffeeImp();
  }
   
  现在我们有了两个抽象c?下面我们分别对其q行l承,实现concrete class:
  
  //中杯
  public class MediumCoffee extends Coffee
  {
    public MediumCoffee() {setCoffeeImp();}
  
    public void pourCoffee()
    {
      CoffeeImp coffeeImp = this.getCoffeeImp();
      //我们以重复次数来说明是冲中杯q是大杯 ,重复2ơ是中杯
      for (int i = 0; i < 2; i++)
      {
  
        coffeeImp.pourCoffeeImp();
      }
    
    }
  }
  
  //大杯
  public class SuperSizeCoffee extends Coffee
  {
    public SuperSizeCoffee() {setCoffeeImp();}
  
    public void pourCoffee()
    {
      CoffeeImp coffeeImp = this.getCoffeeImp();
      //我们以重复次数来说明是冲中杯q是大杯 ,重复5ơ是大杯
      for (int i = 0; i < 5; i++)
      {
  
        coffeeImp.pourCoffeeImp();
      }
    
    }
  }
  
  上面分别是中杯和大杯的具体实?下面再对行ؓCoffeeImpq行l承:
  
  //加奶
  public class MilkCoffeeImp extends CoffeeImp
  {
    MilkCoffeeImp() {}
  
    public void pourCoffeeImp()
    {
      System.out.println("加了味的牛?);
    }
  }
  
  //不加?br />   public class FragrantCoffeeImp extends CoffeeImp
  {
    FragrantCoffeeImp() {}
  
    public void pourCoffeeImp()
    {
      System.out.println("什么也没加,清香");
    }
  }
  
  Bridge模式的基本框架我们已l搭好了,别忘记定义中q有一?动态结?我们现在可以喝到臛_四种咖啡:
  1.中杯加奶
  2.中杯不加?br />   3.大杯加奶
  4.大杯不加?br />   
  看看是如何动态结合的,在用之?我们做个准备工作,设计一个单态类(Singleton)用来hold当前的CoffeeImp:
  
  public class CoffeeImpSingleton
  {
    private static CoffeeImp coffeeImp;
  
    public CoffeeImpSingleton(CoffeeImp coffeeImpIn)
     {this.coffeeImp = coffeeImpIn;}
  
    public static CoffeeImp getTheCoffeeImp()
    {
      return coffeeImp;
    }
  }
  
  看看中杯加奶 和大杯加?是怎么出来?
  
  //拿出牛奶
  CoffeeImpSingleton coffeeImpSingleton = new CoffeeImpSingleton(new MilkCoffeeImp());
  
  //中杯加奶
  MediumCoffee mediumCoffee = new MediumCoffee();
  mediumCoffee.pourCoffee();
  
  //大杯加奶
  SuperSizeCoffee superSizeCoffee = new SuperSizeCoffee();
  superSizeCoffee.pourCoffee();
  
  注意: Bridge模式的执行类如CoffeeImp和Coffee是一对一的关p? 正确创徏CoffeeImp是该模式的关?
  
  Bridge模式在EJB中的应用
  EJB中有一个Data Access Object (DAO)模式,q是商业逻辑和具体数据资源分开?因ؓ不同的数据库有不同的数据库操?操作不同数据库的行为独立抽象成一个行为接口DAO.如下:
  
  1.Business Object (cMCoffee)
  
  实现一些抽象的商业操作:如寻找一个用户下所有的订单
  
  涉及数据库操作都使用DAOImplementor.
  
  2.Data Access Object (cMCoffeeImp)
  
  一些抽象的Ҏ(gu)据库资源操作
  
  3.DAOImplementor 如OrderDAOCS, OrderDAOOracle, OrderDAOSybase(cMMilkCoffeeImp FragrantCoffeeImp)
  
  具体的数据库操作,?INSERT INTO "{语?OrderDAOOracle是Oracle OrderDAOSybase是Sybase数据?
  
  4.数据?(Cloudscape, Oracle, or Sybase database via JDBC API)


bacoo 2007-12-20 23:38 发表评论
]]>
[转蝲]设计模式学习(fn)W记(?—Bridge桥接模式http://www.tkk7.com/bacoo/archive/2007/12/20/169183.htmlbacoobacooThu, 20 Dec 2007 15:37:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169183.htmlhttp://www.tkk7.com/bacoo/comments/169183.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169183.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169183.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169183.html《设计模式》一书对Bridge是这hq的Q?/font>

抽象与其实现解耦,使它们都可以独立地变化?/span>

大致意思是_一l实C另一l用他们的对象分离。这里的实现指的是抽象类及其

zcȝ来实现自q对象Q而不是抽象类的派生类Q这些派生类被称为具体类Q。下?/span>

是《Design Patterns Explained》书中的例子。其l构囑֦下:
  

下面是它的实玎ͼ

abstract class Shape{

    protected Drawing myDrawing;

    abstract public void draw();

    Shape(Drawing drawing){

        myDrawing=drawing;

    }

    protected void drawLine(){

        myDrawing.drawLine();

    }

    protected void drawCircle(){

        myDrawing.drawCircle();

    }

}

class Rectangle extends Shape{

    public Rectangle(Drawing darw){

        super(darw);

    }

    public void draw(){

        drawLine();

        drawLine();

        drawLine();

        drawLine();

    }

}

 class Circle extends Shape{

    public Circle(Drawing draw){

        super(draw);

    }

    publicvoid draw(){

        myDrawing.drawCircle();

    }

}

abstract class Drawing{

    abstract public void drawLine();

    abstract public void drawCircle();

}

class V1Drawing extends Drawing{

    public void drawLine(){

        DP1.draw_a_line();

    }

    public void drawCircle(){

        DP1.draw_a_circle();

    }

}

class V2Drawing extends Drawing{

    public void drawLine(){

        DP2.drawLine();

    }

    public void drawCircle(){

        DP2.drawCircle();

    }

}

class DP1{

    public static void draw_a_line(){

        System.out.println("使用DP1的draw_a_line()ȝ");

    }

    public static void draw_a_circle(){

        System.out.println("使用DP1的draw_a_circle()d");

    }

}

class DP2{

    public static void drawLine(){

        System.out.println("使用DP2的drawLine()ȝ");

    }

    public static void drawCircle(){

        System.out.println("使用DP2的drawCircle()d");

    }

}

 public class BridgeClient {

    public static void main(String[] args) {

        Drawing draw1=new V1Drawing();

        Drawing draw2=new V2Drawing();

        Shape shape1=new Rectangle(draw1);

        shape1.draw();

        Shape shape2=new Circle(draw2);

        shape2.draw();

    }

}

输出l果如下Q?/span>

使用DP1?/span>draw_a_line()ȝ

使用DP1?/span>draw_a_line()ȝ

使用DP1?/span>draw_a_line()ȝ

使用DP1?/span>draw_a_line()ȝ

使用DP2?/span>drawCircle()d

在这个例子中Shape对象实际上是一?/span>Retangle?/span>Circle对象Q?/span>?/span>Clientq不知道到底是那?/span>Q?/span>因ؓ它们看v来都一栗?/span>Drawing实际上是一?/span>V1Drawing?/span>V2Drawing,?/span>Shape对象q知道到底是哪个Q?/span>因ؓ它们看v来都一栗DP1或DP2使用它的Drawing对象知道是哪一个。Shape是事物的抽象QDrawing是实现或者操作事物方法的抽象。他们两个都可以独立地变化。正如例子中所说那P我们可以输出一个矩形可以用V1Drawing也可以用V2Drawing来完成,输出一个圆形也是一样都有两U方法。Bridge模式遵@了设计模式中两条基本{略Q找出变化ƈ装之和优先使用对象聚集Q而不是类l承?/span>

    结QBridge模式是一U抽象与其实现相分离的模式。它主要应用于:当事物是一l变化量Q和对这些事物的操作Ҏ(gu)(实现)也是一l变化量的情况,也就是说它们都是多变的?/span>



bacoo 2007-12-20 23:37 发表评论
]]>
[转蝲]singleton(单态模?http://www.tkk7.com/bacoo/archive/2007/12/20/169180.htmlbacoobacooThu, 20 Dec 2007 15:21:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169180.htmlhttp://www.tkk7.com/bacoo/comments/169180.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169180.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169180.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169180.html

单态定?/strong>:
Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?

在很多操作中Q比如徏立目?数据库连接都需要这L(fng)单线E操作?

q有, singleton能够被状态化; q样Q多个单态类在一起就可以作ؓ一个状态仓库一样向外提供服务,比如Q你要论坛中的帖子计数器Q每ơ浏览一ơ需要计敎ͼ单态类能否保持住这个计敎ͼq且能synchronize的安全自动加1Q如果你要把q个数字怹保存到数据库Q你可以在不修改单态接口的情况下方便的做到?

另外斚wQSingleton也能够被无状态化。提供工h质的功能,

Singleton模式׃ؓ我们提供了这样实现的可能。用Singleton的好处还在于可以节省内存Q因为它限制了实例的个数Q有利于Java垃圾回收Qgarbage collectionQ?br />
我们常常看到工厂模式中类装入?class loader)中也用Singleton模式实现?因ؓ被装入的cd际也属于资源?br />

如何使用?
一般Singleton模式通常有几UŞ?

public class Singleton {

  private Singleton(){}

  //在自己内部定义自׃个实例,是不是很奇怪?
  //注意q是private 只供内部调用

  private static Singleton instance = new Singleton();

  //q里提供了一个供外部讉K本class的静态方法,可以直接讉K  
  public static Singleton getInstance() {
    return instance;   
   }
}

 

W二UŞ?
public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //q个Ҏ(gu)比上面有所改进Q不用每ơ都q行生成对象Q只是第一ơ     
  //使用时生成实例,提高了效率!
  if (instance==null)
    instanceQnew Singleton();
  return instance;   }

}

 

使用Singleton.getInstance()可以讉K单态类?

上面W二中Ş式是lazy initializationQ也是说第一ơ调用时初始SingletonQ以后就不用再生成了?

注意到l(f)azy initialization形式中的synchronizedQ这个synchronized很重要,如果没有synchronizedQ那么用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴者进一步研I?

一般认为第一UŞ式要更加安全些?br />

使用Singleton注意事项Q?br /> 有时在某些情况下Q用Singletonq不能达到Singleton的目的,如有多个Singleton对象同时被不同的c装入器装蝲Q在EJBq样的分布式pȝ中用也要注意这U情况,因ؓEJB是跨服务器,跨JVM的?

我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocatorZE微分析一下:

在Pet Store中ServiceLocator有两U,一个是EJB目录下;一个是WEB目录下,我们查这两个ServiceLocator会发现内容差不多Q都是提供EJB的查询定位服务,可是Z么要分开呢?仔细研究对这两种ServiceLocator才发现区别:在WEB中的ServiceLocator的采取Singleton模式QServiceLocator属于资源定位Q理所当然应该使用Singleton模式。但是在EJB中,Singleton模式已经失去作用Q所以ServiceLocator才分成两U,一U面向WEB服务的,一U是面向EJB服务的?

Singleton模式看v来简单,使用Ҏ(gu)也很方便Q但是真正用好,是非怸Ҏ(gu)Q需要对Java的类 U程 内存{概忉|相当的了解?

MQ如果你的应用基于容器,那么Singleton模式用或者不用,可以使用相关替代技术?

q一步深入可参考:

Double-checked locking and the Singleton pattern

When is a singleton not a singleton?

设计模式如何在具体项目中应用?a target="_blank">《Java实用pȝ开发指南?/font>

 

Singleton模式的要点:
1、某个类只能有一个实?br /> 2、必自行创个实?br /> 3、必d整个pȝ提供q个实例

Singleton模式的实现方?br /> 1、饿汉式singleton
public class EagerSingleton
{
private static final EagerSingleton m_instance = new Eagersingleton();
private Eagersingleton(){}

public static EagerSingleton getInstance()
{
return m_instance;
}

}

2、懒汉式singleton
public class LazySingleton
{
private static LazySingleton m_instance = null;
private LazySingleton(){};
synchronized public static LazySingleton getInstance()
{
if( m_instance == null )
{
m_instance = new LazySingleton();
}
return m_instance;
}
}

3、登记式singleton
import java.util.HashMap;
public class RegSingleton
{
static private HashMap m_registry = new HashMap();
static
{
RegSingleton x = new regSingleton();
m_registry.put(x.getClass().getName(), x);
}
protect RegSingleton(){}
static public RegSingleton getInstance(String name)
{
if(name == null )
{
name = "RegSingleton";
}
if(m_registry.get(name ) == null )
{
m_registry.put(name, Class.forName(name).newInstance();
}
catch(Exception e)
{
System.out.println("Error happened.");
}
return (RegSingleton)(m_registry.get(name));
}
}

三种Singleton模式的比?/strong>

饿汉?c被加蝲时就被实例化?br /> 懒汉?cd载时Q不被实例化Q在W一ơ引用时实例化?

饿汉式、懒汉式都不能被l承
而登记式可以被ѝ?/p>

bacoo 2007-12-20 23:21 发表评论
]]>
JTable学习(fn)W记http://www.tkk7.com/bacoo/archive/2007/12/20/169178.htmlbacoobacooThu, 20 Dec 2007 15:20:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169178.htmlhttp://www.tkk7.com/bacoo/comments/169178.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169178.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169178.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169178.html构徏一个JTable之前Q应该设计好表格的列头以及行数据Q分别用final数组保存之:
final String [] names={"First Name","Last Name","Favorite Color",
            "Favorite Number","Vegetarian"};
final Object [][] data={
    {"Mark","Andrews","Red",new Integer(2),new Boolean(true)},
    {"Tom","Chung","Green",new Integer(99),new Boolean(false)}
    };
接下来,在创建JTable之前Q需要构Z个实CTableModel接口的AbstractTableModelcȝ实例QTableModel接口规定了JTable如何讉K表格中数据的模型。示例如下:
TableModel dataModel =new AbstractTableModel(){
        public int getColumnCount(){return names.length;}//实现q个函数是必ȝQ因为抽象类AbstractTableModel中ƈ没有实现该函?br />         public int getRowCount(){return data.length;}//实现q个函数是必ȝQ因为抽象类AbstractTableModel中ƈ没有实现该函?br />         public Object getValueAt(int row,int col){return data[row][col];}//实现q个函数是必ȝQ因为抽象类AbstractTableModel中ƈ没有实现该函?br />         public String getColumnName(int column){return names[column];}//如果需要自己来命名列名Uͼ必override该方?br />         @SuppressWarnings("unchecked")
        public Class getColumnClass(int col){return getValueAt(0,col).getClass();}//q个Ҏ(gu)也因该重写,因ؓAbstractTableModel中的实现仅仅?#8220;return Object.class;”Q因此我们需要override该方?br />         public boolean isCellEditable(int row,int col){return true;}//默认均返回falseQ因此如果希望表格的cell能够被编辑,需要overrideq个函数
        public void setValueAt(Object aValue,int row,int col){//默认情况下,该函数的函数体是I的Q因此如果希望表格的cell中的D够被更改Q就必须override该函?br />             System.out.println("Setting value to: "+aValue);
            data[row][col]=aValue;
        }
};
接下来就可以创徏JTable了:
JTable tableView=new JTable(dataModel);
xQ表格已l创v来了。如果需要能够对表格q行更进一步的操作Q比如允许用L(fng)辑表g各个单元格的内容Q就需要看看下面的内容喽:
我个为编辑表格是以列为单位的Q?br /> W一步,需要得到某一列:
TableColumn colorColumn=tableView.getColumn(names[2]);
W二步,需要给该列指定一个实CTableCellEditor接口的编辑类QDefaultCellEditorcdC该接口,因此直接构徏DefaultCellEditorcȝ一个实例就ok了,需要说明的是,该类的实现方法只有三U,而且分别对应需要JCheckBox、JComboBox、JTextField三种cȝ实例Q?br /> colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
W三步,l该列指定一个实CTableCellRenderer接口的的渲染c(或称作呈?表现c)QDefaultTableCellRenderercdC该接口,因此直接构徏DefaultTableCellRenderer的一个实例就ok了:
DefaultTableCellRenderer colorColumnRenderer=new DefaultTableCellRenderer();
        colorColumnRenderer.setBackground(Color.pink);
        colorColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
        colorColumnRenderer.setToolTipText("Click for combo box");
        colorColumn.setCellRenderer(colorColumnRenderer);
需要说明的是,DefaultTableCellRenderer能够讄的内容当然不局限于上述列出的这三个Q还有很多,但是有一点很重要Q就是如果你希望单元格的内容能够按照某种方式来改变,比如用户自己~辑了单元格内容后,我们如果希望单元格呈现的内容能够Ҏ(gu)用户的输入做更多的变化(而不仅仅是简单的字符串替换,如果仅仅是字W串替换的话Q那׃必废q么多事了,DefaultTableCellRendererc自带的setValue实现Ҏ(gu)p够完成Q务了Q,而不在希望单元格的内容一成不变了Q此时就不能单的创徏一个DefaultTableCellRenderercȝ实例了,而是需要创Z个DefaultTableCellRenderercȝzc,而且需要override里面的setValueҎ(gu)Q通常我们都这样做Q?br /> DefaultTableCellRenderer numberColumnRenderer=new DefaultTableCellRenderer(){
        public void setValue(Object value){
            int cellValue=(value instanceof Number) ? ((Number)value).intValue() : 0;
            this.setForeground((cellValue > 30) ? Color.black : Color.red);
            super.setValue(value);
        }
};
在DefaultTableCellRenderercMsetValueҎ(gu)的修饰符为protectedQ因此我们不能直接用DefaultTableCellRenderer的实例来使用该方法,而只能通过l承DefaultTableCellRendererc,然后在类的内部override该方法来实现定制特定的功能,从这里我们也能够更深ȝ理解Z么有些方法要定义成protected了,目的是Z对外不可见,但是又能够通过l承的手D|实现用户自己的定Ӟ而且有些情况q是很必ȝQ比如在该处Q我们可以试想一下,如果用public来修饎ͼ则用户可以直接通过产生实例来引用该Ҏ(gu)Q那么由于该cL作用于整个列的,而不仅仅是一个单元格Q那么当你设定了setValue后,到底是该对列中所有的单元格都有效呢,q是该只Ҏ(gu)一个单元格有效呢,q就很难说了?/p>

bacoo 2007-12-20 23:20 发表评论
]]>
[改编]深入equalsҎ(gu)Q讨论instanceof的用!http://www.tkk7.com/bacoo/archive/2007/12/20/169176.htmlbacoobacooThu, 20 Dec 2007 15:19:00 GMThttp://www.tkk7.com/bacoo/archive/2007/12/20/169176.htmlhttp://www.tkk7.com/bacoo/comments/169176.htmlhttp://www.tkk7.com/bacoo/archive/2007/12/20/169176.html#Feedback0http://www.tkk7.com/bacoo/comments/commentRss/169176.htmlhttp://www.tkk7.com/bacoo/services/trackbacks/169176.htmlequalsҎ(gu)的重要性毋da,只要你想比较的两个对象不仅仅局限在只是同一对象Q即它们的引用相同),你就应该实现equalsҎ(gu),让对象用你认为相{的条g来进行比较?

  下面的内容只是API的规?没有什么太高深的意?但我之所以最先把它列在这?是因些规范在事实中ƈ不是真正能保证得到实现?

1。自反性:对于M引用cd, o.equals(o) == true成立?
2。对U性:如果 o.equals(o1) == true 成立,那么o1.equals(o)==true也一定要成立?
3。传递性:如果 o.equals(o1) == true 成立?nbsp; o1.equals(o2) == true 成立,那么o.equals(o2) == true 也成立?
4。一致性:如果W一ơ调用o.equals(o1) == true成立再o和o1没有改变的情况下以后的Q何次调用都成立?
5。o.equals(null) == true M旉都不成立?
  以上几条规则q不是最完整的表q?详细的请参见API文?br />     但是在hashCode()函数的协定中Q要?#8220;如果Ҏ(gu) equals(Object) Ҏ(gu)Q两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode Ҏ(gu)都必ȝ成相同的整数l果?#8221;Q因此我个h认ؓequalsҎ(gu)q应该加上这W?条规定:
6。如?o.equals(o1) == true 成立,那么必须有o.hashCode==o1.hashCode()?

  对于Objectc?它提供了一个最最严密的实?那就是只有是同一对象?equalsҎ(gu)才返回true,也就是h们常说的引用比较而不是值比较。这个实C密得已经没有什么实际的意义,所以在具体子类(相对于Object来说)?如果我们要进行对象的值比?必d现自qequalsҎ(gu)?

  先来看一下以下这D引自于JDK中的E序:
Q说明:attribute在FieldPosition中有q样的定义:private Format.Field attribute;Q?br />     public boolean equals(Object obj)
    {
        if (obj == null) return false;
        if (!(obj instanceof FieldPosition))
            return false;
        FieldPosition other = (FieldPosition) obj;
        if (attribute == null) {
            if (other.attribute != null) {
                return false;
            }
        }
        else if (!attribute.equals(other.attribute)) {
            return false;
        }
        return (beginIndex == other.beginIndex
            && endIndex == other.endIndex
            && field == other.field);
    }
  q是JDK中java.text.FieldPosition的标准实?g没有什么可说的. 我相信大多数或绝大多数程序员认ؓ,q是正确的合法的equals实现.毕竟它是JDK的API实现? q是让我们以事实来说话吧:

package debug;
import java.text.*;
public class Test {
  public static void main(String[] args) {
    FieldPosition fp = new FieldPosition(10);
    FieldPosition fp1 = new MyTest(10);
    System.out.println(fp.equals(fp1));
    System.out.println(fp1.equals(fp));
  }
}
class MyTest extends FieldPosition{
  int x = 10;
  public MyTest(int x){
    super(x);
    this.x = x;
  }
  public boolean equals(Object o){
    if(o==null) return false;
    if(!(o instanceof MyTest )) return false;
    return ((MyTest)o).x == this.x;
  }
}
   q行一下看看会打印Z?

System.out.println(fp.equals(fp1));打印true
System.out.println(fp1.equals(fp));打印flase  
  两个对象,出现了不对称的equals法.问题出在哪里(脑筋急{弯:当然出在JDK实现的固有BUGQ看来JDK中的东西未必完全都是最最最正确的,我们要敢于怀疑它Q??

  我相信有太多的程序员在实现equalsҎ(gu)旉用过instanceofq行W来q行短\优化的,实事求是地说很长一D|间我也这么用q。太多的教程Q文都l了我们q样的误对{而有些稍有了解的E序员可能知道这L(fng)优化可能有些不对但找不出问题的关键。另外一U极端是知道q个技术缺L(fng)骨灰U专家就提议不要q样应用?

  我们知道Q?通常"要对两个对象q行比较Q那么它?应该"是同一cd。所以首先利用nstanceofq行W进行短路优化(“短\”《Short-circuiting》,而短路的最大好处就是能够优化性能。所谓的短\是当第一个被q算的表辑ּ的结果已l能够决定运的最l结果时Q就不会再去计算其他的表辑ּQ因此可以避免掉额外且不必要的运操作,其是当所略过的是复杂或含有过E调用的表达式时Q短路的性能提升q度更ؓ明显。比如我们在if中同时用&&判断多个条g的时候,遇到W一个false的时候就不会再计后面的表达式是否ؓtrue了)Q如果被比较的对象不和当前对象是同一cd则不用比较返回false,但事实上Q?子类是父cȝ一个实?Q所以如?子类 instanceof 父类Q始l返回true,q时肯定不会发生短\优化Q下面的比较有可能出现多U情况,一U是父类不能造型成子c而抛出异常(比如子类.equals(父类)后,在equals内部会进行试囑ְ父类向下造型成子cȝ操作Q,另一U是父类的private 成员没有被子cȝ承而不能进行比较,q有是形成上面q种不对U比较。可能会出现太多的情c?

  那么Q是不是׃能用 instanceofq行W来q行优化Q答案是否定的,JDK中仍然有很多实现是正的Q如果一个class是final的,明知它不可能有子c,Z么不用instanceof来优化呢Q(可见对于不涉及子cȝ问题Ӟ用instanceofq行短\优化q是很可行的Q?

  Zl护SUN的开发小l的声誉Q我不说明哪个类中,但有一个小l成员在用这个方法优化时在后加加上了加上了这L(fng)注释Q?

if (this == obj)             // quick checkQ也是短\优化Q?br />          return true;
      if (!(obj instanceof XXXXClass))  // (1) same object?
         return false;  可能是有些疑问,但不知道如何做(不知道ؓ什么没有打?sh)话l我......Q?

  那么对于非finalc,如何q行cd的quick check呢?

if(obj.getClass() != XXXClass.class) return false;
  用被比较对象的class对象和当前对象的class比较Q看h是没有问题,但是Q如果这个类的子cL有重新实现equalsҎ(gu)Q那么当子类.equals(子类)比较Ӟ也就是要使用“if(obj.getClass() != XXXClass.class) return false;”来进行比较了Q显然obj.getClass()《这个是字类?肯定不等于XXXCalss.class《这个是父类?从这里就直接q回得到false的结果了Q因此子cM定义的equals实际上根本没发挥出应有的效力来,所以if(obj.getClass() != this.getClass()) return false;才是正确的比较?呵呵Q看C没?我们首先否定了instanceofQ接下来又否定了“obj.getClass() != XXXClass.class”q种错误的比较做法,最后才l出了正的比较Ҏ(gu)?br /> 另外一个quick check是if(this==obj) return true;而且q个短\优化应该攑֜“obj.getClass() != XXXClass.class”优化的前面?

  是否equalsҎ(gu)一定比较的两个对象׃定是要同一cdQ上面我用了"通常"Q这也是l大多数E序员的愿望Q但是有些特D的情况Q我们可以进行不同类型的比较Q这q不q反规范。但q种Ҏ(gu)情况是非常罕见的Q一个不恰当的例子是QIntegercȝequals可以和Sort做比较,比较它们的value是不是同一数学倹{(事实上JDK的API中ƈ没有q样做,所以我才说是不恰当的例子)。在完成quick check以后Q我们就要真正实C认ؓ?#8220;相等”。对于如果实现对象相{,没有太高的要求,比如你自己实现的“?#8221;c,你可以认为只要name相同卌为它们是相等的,其它的sex,ago都可以不考虑。这是不完全实现Q但是如果是完全实现Q即要求所有的属性都是相同的Q那么如何实现equalsҎ(gu)Q?

class Human{
private String name;
private int ago;
private String sex;
  ....................
  public boolean equals(Object obj){
  quick check.......
  Human other = (Human)ojb;
  return this.name.equals(other.name)
   && this.ago == ohter.ago
   && this.sex.equals(other.sex);
}
}
   q是一个完全实玎ͼ但是Q有时equals实现是在父类中实现的Q而且要求被子cȝ承后Q父cȝequals能正的工作Q这时父cM的equalsq不事实知道子类到底扩展了哪些属性,所以用上面的方法无法equals得到完全实现?

  一个好的方法是利用反射来对equalsq行完全实现Q?l出一个完整的在父cM定义的equalsҎ(gu)Q只是比较字D)的实玎ͼ
public boolean equals(Object obj){
  if(obj == this)
      return true;
  if(obj.getClass() != this.getClass())
      return false;
  Class c = this.getClass();
  Filed[] fds = c.getDeclaredFields();
  for(Filed f:fds){
   if(!f.get(this).equals(f.get(obj)))
    return false;
  }
  return true;
}
  Z说明的方便,上明的实现省略了异常Q这L(fng)实现攑֜父类中,可以保证你的子类的equals可以按你的愿望正地工作。当然这里只是考虑了基于字D늛{的比较Q如何还涉及到基于方法等其他斚w的相{比较,则应该扩展上面的代码Q反出更多的东西(比如Ҏ(gu)Q来加以比较判断?

  关于equalsҎ(gu)的最后一Ҏ(gu)Q如果你要是自己重写Q正说应该是盖)了equalsҎ(gu)Q那同时׃定要重写hashCode()Q否?............

  我们q是看一下这个例子:

public final class PhoneNumber {
    private final int areaCode;
    private final int exchange;
    private final int extension;
    public PhoneNumber(int areaCode, int exchange, int extension) {
        rangeCheck(areaCode, 999, "area code");
        rangeCheck(exchange, 99999999, "exchange");
        rangeCheck(extension, 9999, "extension");
        this.areaCode = areaCode;
        this.exchange = exchange;
        this.extension = extension;
    }
    private static void rangeCheck(int arg, int max, String name) {
        if(arg < 0 || arg > max)
            throw new IllegalArgumentException(name + ": " + arg);
    }
    public boolean equals(Object o) {
        if(o == this)
            return true;
        if(!(o instanceof PhoneNumber))
            return false;
        PhoneNumber pn = (PhoneNumber)o;
        return pn.extension == extension && pn.exchange == exchange && pn.areaCode == areaCode;
    }
}
  注意q个cLfinal的,所以这个equals实现没有什么问题?

  我们来测试一?

    public static void main(String[] args) {
        Map hm = new HashMap();
        PhoneNumber pn = new PhoneNumber(123, 38942, 230);
        hm.put(pn, "I love you");
        PhoneNumber pn1 = new PhoneNumber(123, 38942, 230);
        System.out.println(pn);
        System.out.println("pn.equals(pn1) is " + pn.equals(pn1));
        System.out.println(hm.get(pn1));
        System.out.println(hm.get(pn));
    }
  既然pn.equals(pn1),那么我put(pn,"I love you");后,get(pn1)q什么是null呢?

  {案是因为pn和pn1的hashCode不一P而hashMap是以hashCodeZ键的?

  所以根据规范要求(在文章最开始部分提到的标准equalsҎ(gu)需要满的6条性质Q,如果两个对象q行equals比较时如果返回true,那么它们的hashcode要求q回相等的倹{?

此外Q在写hashCode函数Ӟ需要注意:
随便你怎么写,只要保证A.equals(B)一定可以推出A.hashCode()==B.hashCode()pQ当Ӟ应该量使得A.equals(B)==false的时候,使得A.hashCode()量不等于B.hashCode()Q绝对不会相{是不可能的Q但是要量降低概率?

比如Q?br /> public int hashCode() {
        int result;
        result = getName().hashCode();
        result = 29 * result + getBirthday().hashCode();
        return result;
    }
其时是需要你Ҏ(gu)自己的类l出Ҏ(gu)的一U算法,能够满通过该算法得到的q个整数|也就是hashCodeQ能够区别该cȝ各个实例?/p>

bacoo 2007-12-20 23:19 发表评论
]]>
[转蝲]L语言比喻java?2U模?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/20/169175.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Thu, 20 Dec 2007 15:18:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/20/169175.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169175.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/20/169175.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169175.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169175.html</trackback:ping><description><![CDATA[<p>java与模?nbsp; <br /> 在java版看见了q篇文章Q作者以L的语a比喻了java?2U模式,有很好的启发作用Q但可惜没有l出具体的意思,q些都是最单的介绍Q要学习(fn)的话你看一下《ajva与模式》这本书?<br /> 创徏型模? <p>1、FACTORY—追MM不了请吃饭了,麦当劳的鸡翅和肯德基的鸡都是MM爱吃的东西,虽然口味有所不同Q但不管你带MM去麦当劳或肯德基Q只向服务员说“来四个鸡?#8221;p了。麦当劳和肯德基是生鸡翅的Factory <p>工厂模式Q客L(fng)和工厂类分开。消费者Q何时候需要某U品,只需向工厂请求即可。消费者无M改就可以接纳C品。缺Ҏ(gu)当品修Ҏ(gu)Q工厂类也要做相应的修改。如Q如何创建及如何向客L(fng)提供? <p>2、BUILDER—MM最爱听的就?#8220;我爱?#8221;q句话了Q见C同地方的MM,要能够用她们的方a跟她说这句话哦,我有一个多U语a译机,上面每种语言都有一个按键,见到MM我只要按对应的键Q它?yu)p够用相应的语a说出“我爱?#8221;q句话了Q国外的MM也可以轻松搞掂,q就是我?#8220;我爱?#8221;builder。(q一定比军在伊拉克用的译机好卖) <p>建造模式:品的内部表象和品的生成q程分割开来,从而一个徏造过E生成具有不同的内部表象的品对象。徏造模式得品内部表象可以独立的变化Q客户不必知道品内部组成的l节。徏造模式可以强制实行一U分步骤q行的徏造过E? <p>3、FACTORY METHOD—请MM去麦当劳吃汉堡,不同的MM有不同的口味Q要每个都记住是一件烦人的事情Q我一般采用Factory Method模式Q带着MM到服务员那儿Q说“要一个汉?#8221;Q具体要什么样的汉堡呢Q让MM直接跟服务员说就行了? <p>工厂Ҏ(gu)模式Q核心工厂类不再负责所有品的创徏Q而是具体创建的工作交给子类dQ成Z个抽象工厂角Ԍ仅负责给出具体工厂类必须实现的接口,而不接触哪一个品类应当被实例化q种l节? <p>4、PROTOTYPE—跟MM用QQ聊天Q一定要说些深情的话语了Q我搜集了好多肉ȝ情话Q需要时只要copy出来攑ֈQQ里面p了,q就是我的情话prototype了。(100块钱一份,你要不要Q? <p>原始模型模式Q通过l出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的Ҏ(gu)创徏出更多同cd的对象。原始模型模式允许动态的增加或减品类Q品类不需要非得有M事先定的等U结构,原始模型模式适用于Q何的{l构。缺Ҏ(gu)每一个类都必配备一个克隆方法? <p>5、SINGLETON—俺?个漂亮的老婆Q她们的老公都是我,我就是我们家里的老公SigletonQ她们只要说?#8220;老公”Q都是指的同一个hQ那是?刚才做了个梦啦,哪有q么好的? <p>单例模式Q单例模式确保某一个类只有一个实例,而且自行实例化ƈ向整个系l提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用? <p>l构型模? <p>6、ADAPTER—在朋友聚会上碰C一个美女SarahQ从香港来的Q可我不会说_语Q她不会说普通话Q只好求助于我的朋友kent了,他作为我和Sarah之间的AdapterQ让我和Sarah可以怺交谈?也不知道他会不会耍我) <p>适配器(变压器)模式Q把一个类的接口变换成客户端所期待的另一U接口,从而原本因接口原因不匚w而无法一起工作的两个c能够一起工作。适配cd以根据参数返q一个合适的实例l客L(fng)? <p>7、BRIDGE—早上碰到MMQ要说早上好Q晚上碰到MMQ要说晚上好Q碰到MMI了件新服Q要说你的衣服好漂亮哦,到MM新做的发型,要说你的头发好漂亮哦。不要问?#8220;早上到MM新做了个发型怎么?#8221;q种问题Q自qBRIDGEl合一下不p? <p>桥梁模式Q将抽象化与实现化脱耦,使得二者可以独立的变化Q也是说将他们之间的强兌变成弱关联,也就是指在一个Y件系l的抽象化和实现化之间用组?聚合关系而不是承关p,从而两者可以独立的变化? <p>8、COMPOSITE—Mary今天q生日?#8220;我过生日Q你要送我一件礼物?#8221;“嗯,好吧Q去商店Q你自己挑?#8221;“qgT恤挺漂亮Q买Q这条裙子好看,乎ͼq个包也不错Q买?#8221;“喂,C三g了呀Q我只答应送一件礼物的哦?#8221;“什么呀QT恤加裙子加包包,正好配成一套呀Q小姐,ȝ你包h?#8221;“……”QMM都会用Composite模式了,你会了没有? <p>合成模式Q合成模式将对象l织到树(wi)l构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的?wi)结构的模式。合成模式把部分与整体的关系用树(wi)l构表示出来。合成模式得客L(fng)把一个个单独的成分对象和׃们复合而成的合成对象同{看待? <p>9、DECORATOR—Maryq完轮到Sarlyq生日,q是不要叫她自己挑了Q不然这个月伙食费肯定玩完,拿出我去q在华山上照的照片Q在背面写上“最好的的礼物,是׃的Fita”Q再到街上礼品店C个像框(卖礼品的MM也很漂亮哦)Q再N壁搞术设计的Mike设计了一个漂亮的盒子装v?#8230;…Q我们都是DecoratorQ最l都在修饰我q个人呀Q怎么P看懂了吗Q? <p>装饰模式Q装饰模式以对客L(fng)透明的方式扩展对象的功能Q是l承关系的一个替代方案,提供比承更多的灉|性。动态给一个对象增加功能,q些功能可以再动态的撤消。增加由一些基本功能的排列l合而生的非常大量的功能? <p>10、FACADE—我有一个专业的Nikon相机Q我喜Ƣ自己手动调光圈、快门,q样照出来的照片才专业,但MM可不懂这些,教了半天也不会。幸好相机有Facade设计模式Q把相机调整到自动档Q只要对准目标按快门p了,一切由相机自动调整Q这样MM也可以用q个相机l我拍张照片了? <p>    门面模式Q外部与一个子pȝ的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系l更易于使用。每一个子pȝ只有一个门面类Q而且此门面类只有一个实例,也就是说它是一个单例模式。但整个pȝ可以有多个门面类? <p>11、FLYWEIGHT—每天跟MM发短信,手指都篏MQ最q买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了Q再不用一个字一个字敲了。共享的句子是FlyweightQMM的名字就是提取出来的外部特征Q根据上下文情况使用? <p>    享元模式QFLYWEIGHT在拳?yn)L赛中指最轻量U。n元模式以׃n的方式高效的支持大量的细_度对象。n元模式能做到׃n的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部Q不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能媄响内蕴状态,它们是相互独立的。将可以׃n的状态和不可以共享的状态从常规cM区分开来,不可以׃n的状态从c里剔除出去。客L(fng)不可以直接创׃n的对象,而应当用一个工厂对象负责创׃n的对象。n元模式大q度的降低内存中对象的数量? <p>12、PROXY—跟MM在网上聊天,一开头L“hi,你好”,“你从哪儿来呀Q?#8221;“你多大了Q?#8221;“w高多少呀Q?#8221;q些话,真烦人,写个E序做ؓ我的Proxy吧,凡是接收到这些话都设|好了自动的回答Q接收到其他的话时再通知我回{,怎么P酷吧? <p>    代理模式Q代理模式给某一个对象提供一个代理对象,q由代理对象控制Ҏ(gu)对象的引用。代理就是一个h或一个机构代表另一个h或者一个机构采取行动。某些情况下Q客户不x者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客L(fng)分L不出代理主题对象与真实主题对象。代理模式可以ƈ不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,q时候代理对象不能够创徏被代理对象,被代理对象必Lpȝ的其他角色代为创建ƈ传入? <p>行ؓ模式 <p>13、CHAIN OF RESPONSIBLEITY—晚上去上英语课Qؓ了好开溜坐C最后一排,哇,前面坐了好几个漂亮的MM哎,扑ּU条Q写?#8220;Hi,可以做我的女朋友吗?如果不愿意请向前?#8221;Q纸条就一个接一个的传上MQ糟p,传到W一排的MM把纸条传l老师了,听说是个老处奛_Q快? <p>   责Q链模式:在责任链模式中,很多对象由每一个对象对其下家的引用而接 <p>    h形成一条链。请求在q个链上传递,直到链上的某一个对象决定处理此h。客户ƈ不知道链上的哪一个对象最l处理这个请求,pȝ可以在不影响客户端的情况下动态的重新l织铑֒分配责Q。处理者有两个选择Q承担责L者把责Q推给下家。一个请求可以最l不被Q何接收端对象所接受? <p>14、COMMAND—俺有一个MM安得特别严,没法见面Q只好借助于她弟弟在我们俩之间传送信息,她对我有什么指C,写一张纸条让她弟弟带l我。这不,她弟弟又传送过来一个COMMANDQؓ了感谢他Q我请他吃了杂酱面Q哪知道他说Q?#8220;我同时给我姐姐三个男朋友送COMMANDQ就C最气Q才h吃面?#8221;Q?-( <p>    命o模式Q命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命o的责d执行命o的责d割开Q委z不同的对象。命令模式允许请求的一方和发送的一方独立开来,使得h的一方不必知道接收请求的一方的接口Q更不必知道h是怎么被接Ӟ以及操作是否执行Q何时被执行以及是怎么被执行的。系l支持命令的撤消? <p>15、INTERPRETER—俺有一个《MM真经》,上面有各UMM的攻略,比如说去吃西的步骤、去看电(sh)qҎ(gu){等Q跟MMU会Ӟ只要做一个InterpreterQ照着上面的脚本执行就可以了? <p>    解释器模式:l定一个语a后,解释器模式可以定义出其文法的一U表C,q同时提供一个解释器。客L(fng)可以使用q个解释器来解释q个语言中的句子。解释器模式描q怎样在有了一个简单的文法后,使用模式设计解释q些语句。在解释器模式里面提到的语言是指M解释器对象能够解释的Ml合。在解释器模式中需要定义一个代表文法的命ocȝ{l构Q也是一pd的组合规则。每一个命令对象都有一个解释方法,代表对命令对象的解释。命令对象的{l构中的对象的Q何排列组合都是一个语a? <p>16、ITERATOR—我׃了MaryQ不一切的向她求婚? <p>          MaryQ?#8220;惌我跟你结婚,得答应我的条?#8221; <p>          我:“什么条件我都答应,你说?#8221; <p>          MaryQ?#8220;我看上了那个一克拉的钻?#8221; <p>          我:“我买Q我乎ͼq有吗?” <p>          MaryQ?#8220;我看上了湖边的那栋别?#8221; <p>          我:“我买Q我乎ͼq有吗?” <p>          MaryQ?#8220;你的弟弟必要?0cm?#8221; <p>          我脑袋嗡的一壎ͼ坐在椅子上,一咬牙Q?#8220;我剪Q我剪,q有吗?” <p>          …… <p>    q代子模式:q代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起Ş成的MUC集,聚集对象是能够包容一l对象的容器对象。P代子模式P代逻辑装C个独立的子对象中Q从而与聚集本n隔开。P代子模式化了聚集的界面。每一个聚集对象都可以有一个或一个以上的q代子对象,每一个P代子的P代状态可以是彼此独立的。P代算法可以独立于聚集角色变化? <p>17、MEDIATOR—四个MM打麻,怺之间谁应该给谁多钱不清楚了,q怺当时我在旁边Q按照各自的{码数算钱,赚了q从我q里拿,赔了q也付l我Q一切就O(jin)K啦,俺得C四个MM的电(sh)话? <p>    调停者模式:调停者模式包装了一pd对象怺作用的方式,使得q些对象不必怺明显作用。从而他们可以松散偶合。当某些对象之间的作用发生改变时Q不会立卛_响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的怺作用转化Z对多的相互作用。调停者模式将对象的行为和协作抽象化,把对象在尺度的行ؓ上与其他对象的相互作用分开处理? <p>18、MEMENTO—同时跟几个MM聊天Ӟ一定要记清楚刚才跟MM说了些什么话Q不然MM发现了会不高兴的哦,q怺我有个备忘录Q刚才与哪个MM说了什么话我都拯一份放到备忘录里面保存Q这样可以随时察看以前的记录啦? <p>    备忘录模式:备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏装的条件下Q将一个对象的状态捉住,q外部化Q存储v来,从而可以在来合适的时候把q个对象q原到存储v来的状态? <p>19、OBSERVER—想知道׃公司最新MM情报吗?加入公司的MM情报邮gl就行了Qtom负责搜集情报Q他发现的新情报不用一个一个通知我们Q直接发布给邮gl,我们作ؓ订阅者(观察者)可以及时收到情报啦 <p>    观察者模式:观察者模式定义了一U一队多的依赖关p,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化Ӟ会通知所有观察者对象,使他们能够自动更新自己? <p>20、STATE—跟MM交往Ӟ一定要注意她的状态哦Q在不同的状态时她的行ؓ会有不同Q比如你U她今天晚上ȝ?sh)媄Q对你没兴趣的MM׃?#8220;有事情啦”Q对你不讨厌但还没喜Ƣ上的MM׃?#8220;好啊Q不q可以带上我同事么?”Q已l喜Ƣ上你的MM׃?#8220;几点钟?看完?sh)媄再去泡吧怎么P”Q当然你看电(sh)pE中表现良好的话Q也可以把MM的状态从不讨厌不喜欢变成喜欢哦? <p>    状态模式:状态模式允怸个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一栗状态模式把所研究的对象的行ؓ包装在不同的状态对象里Q每一个状态对象都属于一个抽象状态类的一个子cR状态模式的意图是让一个对象在其内部状态改变的时候,其行Z随之改变。状态模式需要对每一个系l可能取得的状态创立一个状态类的子cR当pȝ的状态变化时Q系l便改变所选的子类? <p>21、STRATEGY—跟不同cd的MMU会Q要用不同的{略Q有的请?sh)媄比较好,有的则去吃小吃效果不错,有的LvҎ(gu)漫最合适,单目的都是ؓ了得到MM的芳心,我的qMM锦囊中有好多Strategy哦? <p>    {略模式Q策略模式针对一l算法,每一个算法封装到h共同接口的独立的cMQ从而得它们可以相互替换。策略模式得算法可以在不媄响到客户端的情况下发生变化。策略模式把行ؓ和环境分开。环境类负责l持和查询行为类Q各U算法在具体的策略类中提供。由于算法和环境独立开来,法的增减,修改都不会媄响到环境和客L(fng)? <p>22、TEMPLATE METHOD——看q《如何说服女生上床》这部经典文章吗Q女生从认识C床的不变的步骤分为y遇、打破僵局、展开q求、接吅R前戏、动手、爱抚、进d大步?Template method)Q但每个步骤针对不同的情况,都有不一L(fng)做法Q这p看你随机应变?具体实现)Q? <p>    模板Ҏ(gu)模式Q模板方法模式准备一个抽象类Q将部分逻辑以具体方法以及具体构造子的Ş式实玎ͼ然后声明一些抽象方法来q子类实现剩余的逻辑。不同的子类可以以不同的方式实现q些抽象Ҏ(gu)Q从而对剩余的逻辑有不同的实现。先制定一个顶U逻辑框架Q而将逻辑的细节留l具体的子类d现? <p>23、VISITOR—情CQ要l每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个h的特点,每张卡片也要Ҏ(gu)个h的特Ҏ(gu)挑,我一个h哪搞得清楚,q是找花店老板和礼品店老板做一下VisitorQ让花店老板Ҏ(gu)MM的特炚w一束花Q让C品店老板也根据每个h特点选一张卡Q这样就L多了Q? <p>    讉K者模式:讉K者模式的目的是封装一些施加于某种数据l构元素之上的操作。一旦这些操作需要修改的话,接受q个操作的数据结构可以保持不变。访问者模式适用于数据结构相Ҏ(gu)定的pȝQ它把数据结构和作用于结构上的操作之间的耦合解脱开Q得操作集合可以相对自q演化。访问者模式得增加新的操作变的很Ҏ(gu)Q就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中Q而不是分散到一个个的节点类中。当使用讉K者模式时Q要尽可能多的对象览逻辑攑֜讉K者类中,而不是放到它的子cM。访问者模式可以跨q几个类的等U结构访问属于不同的{l构的成员类?nbsp; <h4><a href="http://www.tkk7.com/JavaExplore/archive/2006/08/24/65629.html">《java与模式》笔?zz)</a></h4> <p>虽然自认己对设计模式已经很了解了,但是从来没有pȝ的看q设计模式相关的?最q在公司发现一?lt;java与模?gt;,正好pȝ的看一?下面是这几天记的W记.(q不是系l的讲解书中的内?<br /> 一  lD:<br /> 1、不要用接口定义常?br /> 2、自己少用标志接?br /> 3、不要承具体类<br /> 4、类层次的中间节点应该是接口或者抽象类Q叶子是具体c?br /> 5、子cd当扩展父cȝ责QQ而不是覆写父cȝ责Q<br /> 6、面向接口编E?br /> 7、不要滥用承,l合优先于? <p>java中设计不当的c:calendar:作ؓ接口Q含有与具体的历法(|马历法Q相关的帔RQ不能扩展到中国的阴历历法(不符合开闭原则)<br />                     properiesc:滥用l承Q承至hashtableQ应当用聚? <p>8、笛比特法则Q只与自q直接朋友通信Q不与陌生h通信Q?Q狭义笛比特法则Q只与朋友通讯Q通过自己的朋友传递间接的调用Q?Q结合依赖倒{原则修改Q不必通过朋友传递间接的调用Q通过陌生人的抽象接口调用陌生人的行ؓQ依旧不能与具体的陌生h发生通信Q?br /> 9、尽量降低类中成员的讉K权限Q不要设计退化类Q类似c中structQ?br />         java中的point2D以及Dinmension2DcLq种设计~陷Q不q这U情况问题不大)<br /> 10、如果多个具体的产品cL有共同的商业逻辑Q就可以把它们抽象到一个接口中Q如果有共同的商业逻辑Q就把共同的部分抽象到抽象类中,共同的部分尽量向cȝ承层ơ的上层UdQ以辑ֈ复用的目?br /> ?nbsp;  工厂模式<br /> 1、简单工厂模式:参与角色Q工?抽象产品c?具体产品c? <p>   ~点Q添加新产品的时候,虽然产品相关代码W合开闭原则,但对工厂cLwƈ不符合,需要修改其中的产生产品Ҏ(gu)或者添加新的生方法(工厂里实现的不同造成的修改不同)来支持新的品类<br />    退化方式:省略掉工厂角Ԍ抽象产品cLd体品类的工厂角Ԍ提供静态的getInstanceҎ(gu)Q比如javacd中的DateFormatc,Q本样很不符合开闭原则,父类中出C具体子类相关的代码,不方便扩展,dC品的时候,修改的时候缺点与原简单工厂的工厂角色cMQ? <p>2、工厂方法模式:参与角色Q抽象工厂类/具体工厂c?抽象产品c?具体产品c?br />      消除了简单工厂的~点 <p>3、抽象工厂模式:单工厂模式与工厂Ҏ(gu)模式的结? <p>4、单例模式:饿汉和懒汉两U,前者将本n对象作ؓ静态私有属性事先生成,后者推q到调用的时候,后者需要考虑多线E的时候,前面需要加U程安全关键字(注意Q,java中还是前者ؓ优?br />    不要滥用单例Q只有系l要求只有一个类的实例的时候才调用<br />    有的单例可能有状态属性,q就为多例模式提供了可能<br />    含有U有属性的cM成单例的时候尤其要注意Q一是私有属性的U程安全Q确实需要的时候可以加U程安全关键字,比如pȝ中的logc,二是认q些属性是不是可以所有线E共享的Q类似普通类的static<br /> ?nbsp;  各种具体模式Q?Q?br /> 1、徏造模式:参与角色4个:指导者、抽象徏造对象、具体徏造对象、?br />       一个复杂的产品有很多的雉Ӟ可以用具体的建造对象来一一构?br /> 2、原始模式:深拷贝、浅拯<br /> 3、适配器模式:adapteec适配成目标接?br /> 4、合成模式:参与角色Qcomposite接口、树(wi)枝节点类、树(wi)叶节点类<br />       分成透明式和安全式两U,各有优缺?br />       (1)前者将理子对象的Ҏ(gu)攑ֈ接口中,q样?wi)型l构中的所有对象都是透明的,都可以统一调用Q但是叶节点q没有管理子对象的能力,因此透明但不安全<br />       (2)后者将理子对象的Ҏ(gu)下放到树(wi)枝节点类中,q样安全但不透明<br /> 5、装饰模式:l承已有cȝ接口Q提供和已有cȝ同的Ҏ(gu)Qƈ对已有类的功能提供扩展(通过l合已有对象Q调用已有对象方法的时候加入新的代码)<br />       (1)透明的装饰模式(Ua的装饰模式)Q装饰类、被装饰cȝ承于同一接口Q而且装饰cd实现接口的方法,不提供额外方法的实现Q调用该cȝ时候用接口声明调用(实例化当然还是自q构造函敎ͼQ即该类的所有方法都是透明?br />       (2)半透明的装饰模式(退化的装饰模式Q:装饰cR被装饰cȝ承于同一接口Q装饰类不仅实现接口的方法,q提供额外方法的实现Q这栯调用它独特的Ҏ(gu)的时候就必须使用它本w来调用Q退化到一半装饰模式、一半适配器模式?/p> <img src ="http://www.tkk7.com/bacoo/aggbug/169175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-20 23:18 <a href="http://www.tkk7.com/bacoo/archive/2007/12/20/169175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转蝲]Java安装后JDK/bin目录下的exe文g的用?/title><link>http://www.tkk7.com/bacoo/archive/2007/12/20/169173.html</link><dc:creator>bacoo</dc:creator><author>bacoo</author><pubDate>Thu, 20 Dec 2007 15:17:00 GMT</pubDate><guid>http://www.tkk7.com/bacoo/archive/2007/12/20/169173.html</guid><wfw:comment>http://www.tkk7.com/bacoo/comments/169173.html</wfw:comment><comments>http://www.tkk7.com/bacoo/archive/2007/12/20/169173.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/bacoo/comments/commentRss/169173.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/bacoo/services/trackbacks/169173.html</trackback:ping><description><![CDATA[<p><strong>javacQ?/strong>Java~译器,Java源代码换成字节代 <br /> <strong>javaQ?/strong>Java解释器,直接从类文g执行Java应用E序代码 <br /> <strong>appletviewer(程序浏览器)Q?/strong>一U执行HTML文g上的Java程序类的Java览?<br /> <strong>javadocQ?/strong>Ҏ(gu)Java源代码及其说明语句生成的HTML文 <br /> <strong>jdbQ?/strong>Java调试器,可以逐行地执行程序、设|断点和查变?<br /> <strong>javahQ?/strong>产生可以调用Javaq程的Cq程Q或建立能被JavaE序调用的Cq程的头文g <br /> <strong>JavapQ?/strong>Java反汇~器Q显C编译类文g中的可访问功能和数据Q同时显C字节代码含?<br /> <strong>jarQ?/strong>多用途的存及压~工P是个java应用E序Q可多个文件合qؓ单个JAR归文g?<br /> <strong>htmlConverterQ?/strong>命o转换工具?<br /> <strong>native2asciiQ?/strong>含有不是Unicode或Latinl字符的的文g转换为Unicode~码字符的文件?<br /> <strong>serialverQ?/strong>q回serialverUID。语法:serialver [show] 命o选项show是用来显CZ个简单的界面。输入完整的cd按Enter键或"昄"按钮Q可昄serialverUID?<br /> <strong>补充详细Q?/strong><br /> <strong>javac.exe</strong> <p>用法Qjavac <选项> <源文?gt; <br /> 可能的选项包括Q?<br /> -g 生成所有调试信?<br /> -g:none 生成无调试信?<br /> -g:{lines,vars,source} 生成只有部分调试信息 <br /> -O 优化Q可能妨调试或者增大类文g <br /> -nowarn 生成无警?<br /> -verbose 输出关于~译器正在做的信?<br /> -deprecation 输出使用了不鼓励使用的API的源E序位置 <br /> -classpath <路径> 指定用户cL件的位置 <br /> -sourcepath <路径> 指定输入源文件的位置 <br /> -bootclasspath <路径> 覆盖自DcL件的位置 <br /> -extdirs <目录(多个)> 覆盖安装的扩展类的位|?<br /> -d <目录> 指定输出cL件的位置 <br /> -encoding <~码> 指定源文件中所用的字符集编?<br /> -target <版本> 生成指定虚拟机版本的cL?<br /> -help Print a synopsis of standard options <p><strong>appletviewer.exe</strong> <p>用法Qappletviewer <options> url <br /> 其中Q?lt;options> 包括Q?<br /> -debug ?Java 调试器中启动 applet 程序查看器 <br /> -encoding <encoding> 指定?HTML 文g使用的字W编?<br /> -J<runtime flag> ?Java 解释器传递参?<br /> -J 选项不是标准选项Q如有更改,不另行通知? <p><strong>jar.exe</strong> <p>用法Qjar {ctxu}[vfm0M] [jar-文g] [manifest-文g] [-C 目录] 文g?... <br /> 选项Q?<br /> -c 创徏新的存档 <br /> -t 列出存内容的列?<br /> -x 展开存中的命名的(或所有的〕文?<br /> -u 更新已存在的存档 <br /> -v 生成详细输出到标准输Z <br /> -f 指定存文g?<br /> -m 包含来自标明文g的标明信?<br /> -0 只存储方式;未用ZIP压羃格式 <br /> -M 不生所有项的清单(manifest〕文?<br /> -i 为指定的jar文g产生索引信息 <br /> -C 改变到指定的目录Qƈ且包含下列文Ӟ <br /> 如果一个文件名是一个目录,它将被递归处理?<br /> 清单Qmanifest〕文件名和存档文件名都需要被指定Q按'm' ?'f'标志指定的相同顺序?<br /> CZ1Q将两个class文g存C个名?'classes.jar' 的存文件中Q?<br /> jar cvf classes.jar Foo.class Bar.class <br /> CZ2Q用一个存在的清单QmanifestQ文?'mymanifest' ?foo/ 目录下的所?<br /> 文g存C个名?'classes.jar' 的存文件中Q?<br /> jar cvfm classes.jar mymanifest -C foo/ . <p><strong>javadoc.exe</strong> <p>用法Qjavadoc [options] [packagenames] [sourcefiles] [classnames] [@files] <br /> -overview <file> d HTML 格式的概q文?<br /> -public 仅显C?public cd成员 <br /> -protected 昄 protected/public cd成员Q缺省) <br /> -package 昄 package/protected/public cd成员 <br /> -private 昄所有类和成?<br /> -help 昄命o行选项 <br /> -doclet <class> 通过候?doclet 生成输出 <br /> -docletpath <path> 指定 doclet cL件的查找位置 <br /> -sourcepath <pathlist> 指定源文件的查找位置 <br /> -classpath <pathlist> 指定用户cL件的查找位置 <br /> -exclude <pkglist> Specify a list of packages to exclude <br /> -subpackages <subpkglist> Specify subpackages to recursively load <br /> -breakiterator Compute 1st sentence with BreakIterator <br /> -bootclasspath <pathlist> 覆盖自Dcd载器所加蝲的类文g的位|?<br /> -source <release> Provide source compatibility with specified release <br /> -extdirs <dirlist> 覆盖已安装的扩展的位|?<br /> -verbose 有关 Javadoc 所做工作的输出信息 <br /> -locale <name> 所用的 LocaleQ例?en_US ?en_US_WIN <br /> -encoding <name> 源文件编码名U?<br /> -J<flag> ?<flag> 直接传给q行时系l?<br /> 由标?doclet 提供Q?<br /> -d <directory> 输出文g的目标目?<br /> -use 创徏cd包的用法?<br /> -version 包含 @version D?<br /> -author 包含 @author D?<br /> -docfilessubdirs Recursively copy doc-file subdirectories <br /> -splitindex 烦引分为每个字母对应一个文?<br /> -windowtitle <text> 文档的浏览器H口标题 <br /> -doctitle <html-code> 包含包烦引页Q首)的标?<br /> -header <html-code> 包含每一늚늜文本 <br /> -footer <html-code> 包含每一늚脚文本 <br /> -bottom <html-code> 包含每一늚底文本 <br /> -link <url> Create links to javadoc output at <url> <br /> -linkoffline <url> <url2> Link to docs at <url> using package list at <url2> <br /> -excludedocfilessubdir <name1>:.. Exclude any doc-files subdirectories with given name. <br /> -group <name> <p1>:<p2>.. Group specified packages together in overview page <br /> -nocomment Supress description and tags, generate only declarations. <br /> -nodeprecated 不包?@deprecated 信息 <br /> -noqualifier <name1>:<name2>:... Exclude the list of qualifiers from the output. <br /> -nosince Do not include @since information <br /> -nodeprecatedlist 不生成不鼓励使用的列?<br /> -notree 不生成类层次 <br /> -noindex 不生成烦?<br /> -nohelp 不生成帮助链?<br /> -nonavbar 不生成导航栏 <br /> -quiet Do not display status messages to screen <br /> -serialwarn Generate warning about @serial tag <br /> -tag <name>:<locations>:<header> Specify single argument custom tags <br /> -taglet The fully qualified name of Taglet to register <br /> -tagletpath The path to Taglets <br /> -charset <charset> Charset for cross-platform viewing of generated documentation. <br /> -helpfile <file> 包含帮助链接功能链接到目标的文g <br /> -linksource Generate source in HTML <br /> -stylesheetfile <path> 改变所生成文的样式的文g <br /> -docencoding <name> 输出~码名称 <p><strong>javah.exe</strong> <p>用法Qjavah [options] <classes> <br /> 其中 [options] 包括Q?br /> -help 打印该帮助信?<br /> -classpath <path> cȝ加蝲路径 <br /> -bootclasspath <path> 自Dcȝ加蝲路径 <br /> -d <dir> 输出目录 <br /> -o <file> 输出文gQ仅能?-d ?-o 之一Q?<br /> -jni 生成 JNI 风格的头文gQ缺省) <br /> -old 生成 JDK1.0 风格的头文g <br /> -stubs 生成 stubs 文g <br /> -version 打印版本信息 <br /> -verbose 输出有关本命令所做工作的信息 <br /> -force 始终写输出文?<br /> 指定 <classes> 时必M用全名(例如 java.lang.ObjectQ? <p><strong>javaw.exe </strong> <p>HtmlConverter.exe <br /> 用法QHtmlConverter [-option1 value1 [-option2 value2 [...]]] [-simulate] [filespecs] <br /> 其中Q选项包括Q?br /> -source: 获取源文件的路径?~省| <userdir> <br /> -dest: 写入已{换文件的路径?~省| <userdir> <br /> -backup: 写备份文件的路径?~省| <dirname>_BAK <br /> -f: 强制覆写备䆾文g?<br /> -subdirs: 应处理子目录中的文g?<br /> -template: 模板文g的\径?如果不确定,请用缺省倹{?<br /> -log: 写日志的路径?如果没有提供Q则不会写入M日志?<br /> -progress: 转换时显C度?~省| true <br /> -simulate: 在没有进行{换时昄特定于{换的信息?<br /> -latest: 使用最新的 JRE 支持发行?mimetype?<br /> -gui: 昄转换E序的图形用L(fng)面?<br /> filespecs: 用空格分开的文件说明列表?~省| "*.html *.htm" Q需要引P <p><strong>orbd.exe</strong> <p>用法Qorbd <选项> <br /> 其中Q?lt;选项> 包括Q?<br /> -port 启动 ORBD 的激zȝ口,~省gؓ 1049 (可? <br /> -defaultdb ORBD 文g的目录,~省gؓ "./orb.db" (可? <br /> -serverid ORBD 的服务器标识W,~省gؓ 1 (可? <br /> -ORBInitialPort 初始端口Q必需Q?<br /> -ORBInitialHost 初始L名称Q必需Q? <p><strong>policytool.exe</strong> <p>用法Qpolicytool [选项] <br /> [-file <file>] 规则文g位置 <p><strong>rmic.exe</strong> <p>用法Qrmic <选项> <cd><br /> 其中 <选项> 包括Q?<br /> -keep 不删除中间生成的源文?<br /> -keepgenerated Q同 "-keep") <br /> -v1.1 ?1.1 stub 协议版本创徏 stubs/skeleton <br /> -vcompat Q缺省)创徏?1.1 ?<br /> 1.2 stub 协议版本兼容?stubs/skeleton <br /> -v1.2 仅ؓ 1.2 stub 协议版本创徏 stubs <br /> -iiop ?IIOP 创徏 stubs。当使用该选项Ӟ<选项>q应包括Q?<br /> -always d?stubs Q即使在它们同时出现时?<br /> -alwaysgenerate (?"-always") <br /> -nolocalstubs 不创Zؓ同一q程优化?stubs <br /> -idl 创徏 IDL。当使用该选项Ӟ<选项>q应包括Q?<br /> -noValueMethods 不生成值类型的Ҏ(gu) <br /> -always d?IDL Q即使在它们同时出现时?<br /> -alwaysgenerate (?"-always") <br /> -g 一般调试信?<br /> -depend 以递归方式重编译过期的文g <br /> -nowarn 不警?<br /> -nowrite 不将~译q的cd入到文gpȝ <br /> -verbose 输出有关~译器所做工作的信息 <br /> -classpath <path> 指定输入源和cL件的查找位置 <br /> -sourcepath <path> 指定用户源文件的查找位置 <br /> -bootclasspath <path> 覆盖自DcL件的位置 <br /> -extdirs <path> 覆盖安装扩展cȝ位置 <br /> -d <directory> 指定所生成cL件的攄位置 <br /> -J<runtime flag> 参Cl?java 解释E序 <p><strong>rmid.exe</strong> <p>用法Qrmid <option> <br /> 其中Q?lt;option> 包括: <br /> -port <option> 指定?rmid 使用的端?<br /> -log <directory> 指定 rmid 日志写入的目录 <br /> -stop 停止当前?rmid 调用Q对指定端口Q?<br /> -C<runtime 标记> 向每个子q程传递参敎ͼȀzȝQ?<br /> -J<runtime 标记> ?java 解释E序传递参? <p><strong>rmiregistry.exe</strong> <p>用法Q?rmiregistry <选项> <端口><br /> 其中Q?lt;选项> 包括Q?<br /> -J<runtime 标记> 参C递到 java 解释E序 <p><strong>serialver.exe</strong> <p>用法Qserialver [-classpath classpath] [-show] [classname...] <p><strong>servertool.exe</strong> <p>Ƣ迎使用 Java IDL 服务器工?<br /> 请在提示处输入命?br /> servertool > help <br /> 可用命oQ?<br /> register - 注册一个可Ȁzȝ服务?<br /> unregister - 取消服务器注?<br /> getserverid - q回应用E序名称的服务器标识W?<br /> list - 列D所有已注册服务?<br /> listappnames - 列D当前定义的应用程序名U?<br /> listactive - 列D当前zd的服务器 <br /> locate - 已注册服务器定位在特定cd的端?<br /> locateperorb - 为已注册服务器的特定对象h代理E序定位端口?<br /> orblist - 对象h代理E序 (orb) 名称及其映射列表 <br /> shutdown - 关闭一个已注册服务?<br /> startup - 启动一个已注册服务?<br /> help - 取得帮助 <br /> quit - 退出此工具 <p><strong>rmic</strong> <p>功能说明Q?<br /> rmic E对象生?stub ?skeleton?<br /> 语法Q?<br /> rmic [ options ] package-qualified-class-name(s) <br /> 补充说明Q?<br /> rmic ~译器根据编译后?Java c(含有q程对象实现Q名Qؓq程对象生成 stub ?skeletonQ远E对象是指实?java.rmi.Remote 接口的对象)。在 rmic 命o中所l的cdLl?javac 命o成功~译且是完全包限定的cR?<br /> 命o选项 <br /> -classpath[路径] 指定 rmic 用于查询cȝ路径。如果设|了该选项Q它?yu)覆盖缺省值或 CLASSPATH 环境变量。目录用冒号分隔?<br /> -d[目录] 指定cdơ的根目录。此选项可用来指?stub ?skeleton 文g的目标目录?<br /> -depend 使编译器考虑重新~译从其它类引用的类?一般来_它只重新~译从源代码引用的遗漏或q期的类?<br /> -g 允许生成调试表格。调试表格含有行号和局部变量的有关信息Q即 Java 调试工具所使用的信息。缺省情况下Q只生成行号?<br /> -J ?-D 选项联用Q它?yu)紧跟其后的选项Q?-J ?-D 之间无空|传给 java 解释器?<br /> -keepgenerated ?stub ?skeleton 文g保留所生成?.java 源文Ӟq将q些源文件写C .class 文g相同的目录中Q如果要指定目录Q则使用 -d 选项?<br /> -nowarn 关闭警告。如果用该选项Q则~译器不输出M警告信息?<br /> -show 昄 rmic ~译器的 GUIQ图形用L(fng)面)。输入一个或多个包限定类名(以空格分隔)Qƈ按回车键?#8220;昄”按钮Q创?stub ?skeleton?<br /> -vcompat Q缺省|创徏?JDK 1.1 ?1.2 stub 协议版本都兼容的 stub ?skeleton?<br /> -verbose 使编译器和链接器输出关于正在~译哪些cd正在加蝲哪些cL件的信息?<br /> -v1.1 创徏 JDK 1.1 stub 协议版本?stub ?skeleton?<br /> -v1.2 只创?JDK 1.2 stub 协议版本?stub? <p><strong>rmid</strong> <p>功能说明Q?<br /> rmid 启动Ȁzȝl守护进E,以便能够?Java 虚拟Z注册和激zd象?<br /> 语法Q?<br /> rmid [-port port] [-log dir] <br /> 补充说明Q?<br /> rmid 工具启动Ȁzȝl守护进E。必d启动Ȁzȝl守护进E,才能向激zȝl注册可被激zȝ对象或在 Java 虚拟ZȀzd被激zȝ对象?<br /> 命o选项 <br /> -C<某些命o行选项> 指定一个选项Q在创徏每个 rmid 的子守护q程Q激zȝQ时Q该选项以命令行参数的Ş式传l该子守护进E?<br /> -log[目录] 指定目录的名UͼȀzȝl守护进E在该目录中写入其数据库及相关信息。缺省状态下Q将在执?rmid 命o的目录中创徏一?log 目录?<br /> -port[端口] 指定 rmid 的注册服务程序所使用的端口。激zȝl守护进E将 ActivationSystem 与该注册服务E序中的名称java.rmi.activation.ActivationSystem 捆绑在一赗?<br /> -stop 停止 -port 选项所指定端口上的当前 rmid 调用。若未指定端口,则将停止在端?1098 上运行的 rmid? <p><strong>rmiregistry</strong> <p>功能说明Q?<br /> rmiregistry 命o可在当前L的指定端口上启动q程对象注册服务E序?<br /> 语法Q?<br /> rmiregistry [port] <br /> 补充说明Q?<br /> rmiregistry 命o在当前主机的指定 port 上创建ƈ启动q程对象注册服务E序。如果省?portQ则注册服务E序在 1099 端口上启动。rmiregistry 命o不生Q何输且一般在后台q行。远E对象注册服务程序是自D命名服务。主Z?RMI 服务器将利用它将q程对象l定到名字上。客h卛_查询q程对象q进行远E方法调用。注册服务程序一般用于定位应用程序需调用其方法的W一个远E对象。该对象反过来对各应用程序提供相应的支持Q用于查扑օ它对象。java.rmi.registry.LocateRegistry cȝҎ(gu)可用于在某台L或主机和端口上获取注册服务程序操作。java.rmi.Naming cȝZ URL 的方法将Ҏ(gu)册服务程序进行操作,q可用于查询q程对象、将单(字符Ԍ名称l定到远E对象、将新名U重新绑定到q程对象Q覆盖旧l定Q、取消远E对象的l定以及列出l定在注册服务程序上?URL? <p><strong>serialver </strong> <p>功能说明Q?<br /> serialver 命oq回 serialVersionUID?<br /> 语法Q?<br /> serialver [ 命o选项 ] <br /> 补充说明Q?<br /> serialver 以适于复制到演变类的Ş式返回一个或多个cȝ serialVersionUID。不带参数调用时Q它输出用法行?<br /> 命o选项 <br /> -show 昄一个简单的用户界面。输入完整的cdq按回R键或“昄”按钮可显C?serialVersionUID? <p><strong>jarsigner</strong> <p>功能说明Q?<br /> ?Java 归档 (JAR) 文g产生{֐Qƈ校验已签名的 JAR 文g的签名?<br /> 语法Q?<br /> jarsigner [ 命o选项 ] jar-file alias <br /> jarsigner -verify [ 命o选项 ] jar-file <br /> 补充说明Q?<br /> jarsigner 工具用于两个目的Q?<br /> 1:?Java 归 (JAR) 文g{֐ <br /> 2:校验已签名的 JAR 文g的签名和完整?<br /> 命o选项 <br /> -keystore[url] 指定密钥仓库?URL。缺省值是用户的宿ȝ录中?.keystore 文gQ它ql属?#8220;user.home”军_?<br /> -storetype[storetype] 指定要被实例化的密钥仓库cd。默认的密钥仓库cd是安全属性文件中 "keystore.type" 属性值所指定的那个类型,?java.security.KeyStore 中的静态方?getDefaultType q回?<br /> -storepass[password] 指定讉K密钥仓库所需的口令。这仅在{֐Q不是校验)JAR 文g旉要。在q种情况下,如果命o行中没有提供 -storepass 选项Q用户将被提C入口令?<br /> -keypass[password] 指定用于保护密钥仓库(由命令行中指定的别名标出Q的U钥的口令。?jarsigner ?JAR 文g{֐旉要该口o。如果命令行中没有提供口令,且所需的口令与密钥仓库的口令不同,则将提示用户输入它?<br /> -sigfile[file] 指定用于生成 .SF ?.DSA 文g的基本文件名?<br /> -signedjar[file] 指定用于已签名的 JAR 文g的名U?<br /> -verify 如果它出现在命o行中Q则指定?JAR 文g被校验Q而不是签名。如果校验成功,显C?#8220;jar verified”。如果试图校验未{֐?JAR 文gQ或校验被不支持的算法(例如未安?RSA 提供者时使用?RSAQ签名的 JAR 文gQ则有如下昄Q?"jar is unsigned. (signatures missing or not parsable)" ?<br /> -certs 如果它与 -verify ?-verbose 选项一起出现在命o行中Q则输出包?JAR 文g的每个签名h的证书信息?<br /> -verbose 如果它出现在命o行中Q则代表“verbose”模式Q它?jarsigner ?JAR {֐或校验过E中输出额外信息?<br /> -internalsf q去QJAR 文g被签名时产生?.DSAQ签名块Q文件包含一个同时生的 .SF 文gQ签名文Ӟ的完整编码副本。这U做法已被更攏Vؓ了减输?JAR 文g的整个大,~省情况?.DSA 文g不再包含 .SF 文g的副本。但是如?-internalsf 出现在命令行中,采用旧的做法。该选项主要在测试时有用Q实际上不应使用它,因ؓq样消除有用的优化?<br /> -sectionsonly 如果它出现在命o行中Q则 JAR 文g被签名时生成?.SF 文gQ签名文Ӟ不包括含有整个清单文g的散列的头。它仅包??JAR 中每个单独的源文件相关的信息和散列。该选项主要在测试时有用Q实际上不应使用它,因ؓq样消除有用的优化?<br /> -J[javaoption] 指定的 javaoption 串直接传递到 Java 解释器?Qjarsigner 实际上是解释器的一?“wrapper”Q。该选项不应含有MI格。它有助于调整执行环境或内存使用。要获得可用的解释器选项的清单,可在命o行键?java -h ?java -X? <p><strong>keytool</strong> <p>功能说明Q?<br /> 理q钥和认证相关公钥?X.509 证书铄成的密钥仓库Q数据库Q。还理来自可信d体的证书?<br /> 语法Q?<br /> keytool [ 命o ] <br /> 补充说明Q?<br /> keytool 是个密钥和证书管理工兗它使用戯够管理自q公钥/U钥对及相关证书Q用于(通过数字{֐Q自我认证(用户向别的用?服务认证自己Q或数据完整性以及认证服务。它q允许用户储存他们的通信对等者的公钥Q以证书形式Q? <p><strong>native2ascii</strong> <p>功能说明Q?<br /> 含有本地编码字W(既非 Latin1 又非 Unicode 字符Q的文g转换?Unicode ~码字符的文件?<br /> 语法Q?<br /> native2ascii [options] [inputfile [outputfile]] <br /> 补充说明Q?<br /> Java ~译器和其它 Java 工具只能处理含有 Latin-1 ??Unicode ~码Qudddd 记号Q字W的文g。native2ascii 含有其它字W编码的文g转换成含 Latin-1 ??Unicode ~码字符的文件。若省略 outputfileQ则使用标准输出讑֤输出。此外,如果也省?inputfileQ则使用标准输入讑֤输入?<br /> 命o选项 <br /> -reverse 执行相反的操作:含 Latin-1 ??Unicode ~码字符的文件{换成含本地编码字W的文g?<br /> -encoding[encoding_name] 指定转换q程使用的编码名U。缺省的~码从系l属?file.encoding 中得到? <p><strong>appletviewer</strong> <p>功能说明Q?<br /> Java applet 览器。appletviewer 命o可在q万维|浏览器环境的情况下q行 applet?<br /> 语法Q?<br /> appletviewer [ threads flag ] [ 命o选项 ] urls ... <br /> 补充说明Q?<br /> appletviewer 命oq接?url 所指向的文或资源上,q在其自w的H口中显C文档引用的每个 applet。注意:如果 url 所指向的文档不引用M带有 OBJECT、EMBED ?APPLET 标记?appletQ那?appletviewer ׃做Q何事情?<br /> 命o选项 <br /> -debug ?Java 调试?jdb 中启?appletviewerQ(zhn)可以调试文中?applet?<br /> -encoding[~码名称] 指定输入 HTML 文g的编码名U?<br /> -J[javaoption] ?javaoption 字符串作为单个参Cl运?appletviewer ?Java 解释器。参C能含有空根{由多重参数l成的字W串Q其中的每个参数都必M前缀 -J 开_该前~以后被除去。这在调整编译器的执行环境或内存使用时将很有用? <p><strong>extcheck</strong> <p>功能说明Q?<br /> extcheck 目?jar 文g与当前安装方式扩?jar 文g间的版本冲突?<br /> 语法Q?<br /> extcheck [ -verbose ] targetfile.jar <br /> 补充说明Q?<br /> extcheck 实用E序查指?Jar 文g的标题和版本?JDK TM 软g中所安装的扩展是否有冲突。在安装某个扩展前,可以用该实用E序查看是否已安装了该扩展的相同版本或更高的版本?<br /> extcheck 实用E序?targetfile.jar 文g清单?specification-title ?specification-version 头与当前安装在扩展目录下所?Jar 文g的相对应的头q行比较Q缺省扩展目录ؓ jre/lib/extQ。extcheck 实用E序比较版本L(fng)方式?java.lang.Package.isCompatibleWith Ҏ(gu)相同。若未检到冲突Q则q回代码?0。如果扩展目录中M一?jar 文g的清单有相同?specification-title 和相同的或更新的 specification-version P则返回非雉误代码。如?targetfile.jar 的清单中没有 specification-title ?specification-version 属性,则同栯回非雉误代码?<br /> 命o选项 <br /> -verbose Ҏ(gu)展目录中?Jar 文gq行查时Q列出文件。此外,q报告目?jar 文g的清单属性及所有冲H的 jar 文g? <p><strong>jar</strong> <p>功能说明Q?<br /> Java归档工具 <br /> 语法Q?<br /> jar [ 命o选项 ] [manifest] destination input-file [input-files] <br /> 补充说明Q?<br /> jar工具是个java应用E序Q可多个文件合qؓ单个JAR归档文g。jar是个多用途的存档及压~工P它基于ZIP和ZLIB压羃格式。然而,设计jar的主要目的是便于java applet或应用程序打包成单个归文g。将applet或应用程序的lg(.class 文g、图像和声音)合ƈ成单个归文件时Q可以用java代理(如浏览器)在一ơHTTP事务处理q程中对它们q行下蝲Q而不是对每个lg都要求一个新q接。这大大~短了下载时间。jarq能压羃文gQ从而进一步提高了下蝲速度。此外,它允许applet的作者对文g中的各个进行签名,因而可认证其来源。jar工具的语法基本上与tar命o的语法相同?<br /> 命o选项 <br /> -c 在标准输Z创徏新归或I归档?<br /> -t 在标准输Z列出内容表?<br /> -x[file] 从标准输入提取所有文Ӟ或只提取指定的文件。如果省略了fileQ则提取所有文Ӟ否则只提取指定文件?<br /> -f W二个参数指定要处理的jar文g。在-c(创徏)情Ş中,W二个参数指的是要创建的jar文g的名U?不是在标准输Z)。在-t(??x(抽取)q两U情形中Q第二个参数指定要列出或抽取的jar文g?<br /> -v 在标准错误输备上生成长格式的输出l果?<br /> -m 包括指定的现有清单文件中的清单信息。用法D例:“jar cmf myManifestFile myJarFile *.class” <br /> -0 只储存,不进?ZIP 压羃?<br /> -M 不创建项目的清单文g?<br /> -u 通过d文g或更Ҏ(gu)单来更新现有?JAR 文g。例如:“jar -uf foo.jar foo.class”文?foo.class d到现有的JAR文gfoo.jar中,?#8220;jar umf manifest foo.jar”则用manifest中的信息更新foo.jar的清单?<br /> -C 在执?jar 命o期间更改目录。例如:“jar -uf foo.jar -C classes *”classes目录内的所有文件加到foo.jar中,但不dcȝ录本w?<br /> E序CZ <br /> 1:当前目录下所有CLASS文g打包成新的JAR文gQ?<br /> jar cf file.jar *.class <br /> 2:昄一个JAR文g中的文g列表 <br /> jar tf file.jar <br /> 3:当前目录下的所有文件增加到一个已l存在的JAR文g?<br /> jar cvf file.jar * <p><strong>javadoc</strong> <p>功能说明 <br /> Java API文档生成器从Java源文件生成API文档HTMLc?<br /> 语法Q?<br /> javadoc [ 命o选项 ] [ 包名 ] [ 源文件名 ] [ @files ] <br /> 其中[ 包名 ]为用I格分隔的一pd包的名字Q包名不允许使用通配W,如(*Q。[ 源文件名 ]为用I格?/p> <img src ="http://www.tkk7.com/bacoo/aggbug/169173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/bacoo/" target="_blank">bacoo</a> 2007-12-20 23:17 <a href="http://www.tkk7.com/bacoo/archive/2007/12/20/169173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://csl-chinga.com" target="_blank">һѸƵ</a>| <a href="http://ztxfkj.com" target="_blank">ĻձƬ</a>| <a href="http://dsfv1.com" target="_blank">91Ʒ鶹ϵ</a>| <a href="http://nsmtv.com" target="_blank">պƷרѲ</a>| <a href="http://mordernshasha.com" target="_blank">vaþþþͬ</a>| <a href="http://vankiz.com" target="_blank">гʮ·Ƶ</a>| <a href="http://lzlcp.com" target="_blank">þAAAƬ69</a>| <a href="http://lanchenews.com" target="_blank">ƷСƵapp</a>| <a href="http://kouchoubao.com" target="_blank">Ƶ</a>| <a href="http://linanhotel.com" target="_blank">aһëƬѸ</a>| <a href="http://cc45987.com" target="_blank">ұͨӰƬ߲</a>| <a href="http://tccqdy.com" target="_blank">hƵѸ߹ۿ</a>| <a href="http://hivzx.com" target="_blank">þ޾Ʒۿ</a>| <a href="http://sdcwpfw.com" target="_blank">2022ѹƷ</a>| <a href="http://dxj588.com" target="_blank">ۺպþóAV</a>| <a href="http://cqyouyongpx.com" target="_blank">ƬѸ</a>| <a href="http://see01.com" target="_blank">þþŷղũ</a>| <a href="http://565636.com" target="_blank">þþþùƷѲ </a>| <a href="http://928348.com" target="_blank">91ƬýѰӣ </a>| <a href="http://av56cc.com" target="_blank">mvߵӰ</a>| <a href="http://wwkk3.com" target="_blank">޾ƷӰҹ</a>| <a href="http://langse3.com" target="_blank">ɫվ</a>| <a href="http://bzzxyp.com" target="_blank">һþ</a>| <a href="http://qdhengjun.com" target="_blank">˻ҳվѹۿȫ</a>| <a href="http://cztshw.com" target="_blank">6080yyþԹ </a>| <a href="http://haohaoshuo.com" target="_blank">һAëƬѹۿþþƷ </a>| <a href="http://www6yg6yg.com" target="_blank">ŷ뾫ƷVA </a>| <a href="http://57fi.com" target="_blank">ҹػaëƬѲ</a>| <a href="http://hbtelong.com" target="_blank">ŷպþAV </a>| <a href="http://bjsunic.com" target="_blank">vaþþþͬ</a>| <a href="http://ww99w.com" target="_blank">þùѹۿƷ3</a>| <a href="http://hbwhgd.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://333uy.com" target="_blank">ѹۿվ</a>| <a href="http://69ct.com" target="_blank">ɫëƬƵ</a>| <a href="http://hljjlhl.com" target="_blank">һ</a>| <a href="http://saohuo7.com" target="_blank">ձѲ</a>| <a href="http://wwwby1378.com" target="_blank">ۺavһ</a>| <a href="http://449892.com" target="_blank">߹ۿƬ</a>| <a href="http://chaikexin.com" target="_blank">Ӱۿ</a>| <a href="http://q2c6.com" target="_blank">ֻĻ</a>| <a href="http://789xxoo.com" target="_blank">Ʒjizz߹ۿ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>