随笔 - 20, 文章 - 0, 评论 - 0, 引用 - 0
数据加载中……

[导入]用java匿名类来简化调试

在Java中,匿名类(Anonymous inner classes)多用来处理事件(event handle)。但其实,它们对于debug也很有帮助。本文将介绍如何利用匿名类来简化你的debug。

      我们该如何调试那些非自己源码的方法调用呢?比方说,对Jbutton.setEnable()的调用。Java提供的匿名类,可以很好的解决这个问题。

      通常,当我们继承一个类时,我们可以通过提供新的方法来覆盖(override)该类中现有的方法:
            
public class MyButton extends JButton {   public void setVisible( boolean visible ) {      // Rolling our own visibility    }}
      在实例化(instantiate)MyButton类之后,任何对方法setVisible()的调用,都会调用上面代码中的setVisible()方法。可问题是,我们不想仅仅为了覆盖一个方法而继承整个类,尤其是所需的实例(instantiation)很有限的时候。匿名类使得我们能在实例化的同时覆盖方法。

如果我们只想在某个JButton对象中加入我们自己的可视逻辑,那么我们可以在申明这个button对象的同时重写这个方法:
            
JButton myButton = new JButton() 
{   public void setVisible( boolean visible ) 
{      // Rolling our own visibility    }};
      这段代码都做了什么?花括号({})中间的代码申明了setVisible()方法,并覆盖了JButton类中的那个,但这仅限于myButton对象。我们没有改变JButton类,也没有申明一个新类,我们仅给了一个特殊的JButton对象它自己的可视逻辑。
在面向对象术语中,myButton是一个从JButton类继承而来的无名,也就是匿名,类的对象。

     这种创建匿名类并同时覆盖方法的技术用在什么时候?假设你在编写一段Swing程序,在你向一个GUI物件(element)中添加一个event listener(假设叫作ActionListener)之前,你已经编写了一段这种机制的代码。现在,我们假设我们有个庞大的类,里面有很多按钮,但是有一个按钮时隐时现,你想知道为什么会出这样的异常情况,利用上面的代码并在setVisible()方法上设置断点。然后,当你运行你的程序时,你设置的断点就会在恰当的地方暂停程序。检查栈轨迹(stack trace),我们会发现没有按所预期的那样来调用setVisible()方法的原因并修复这个它。

     匿名类在debug类似这种源码不可得的类的时候很有用。即便在源码可得的情况下,在大量使用的方法(如setVisible)上设置断点,也是件很麻烦的事情,因为我们在每个实现了setVisible()方法的类的对象上都要转入断点。而匿名类可针对某个特定的对象进行“外科手术”式的debug。




文章来源:http://www.blogjava.net/supercrsky/articles/164590.html

posted @ 2009-04-10 13:20 天天开源 阅读(87) | 评论 (0)编辑 收藏

[导入]Java打包详解

jar文件听说过吗,没有?或者陌生!好,没关系,这就是我们的第一站:打包发布。

为什么会有这个玩意呢,首先,这是jar的全称:JavaTM Archive (JAR) file,是的,就是java存档文件。这有点类似zip文件,想一想它是干什么的用的呢,压缩!?没错就是要压缩,将我们原先零散的东西放到一下,重新 组织,所有这些目的只有一个:方便!好了,不用管他是怎么压缩的,我们的重点是哪些是我们要压缩的(输入),还有压缩成了什么(输出),进而将它发布(部 署)。

那我们的输入(要压缩的东西)主要是class文件,还有辅助的资源(这其中可能有图片,jsp文件,html文件等 等)。Jar技术在jdk1.1版本中就已存在,在1.2中又有了增强。接下来说说jar的好处吧,这是官方的描述:安全,快速下载,压缩,猎取包,版本 化包,可携。

说了这么多,我们现在开始实施。

先打开命令提示符(win2000或在运行框里执行cmd命令,win98为DOS提示符),输入jar Chelp,然后回车(如果你盘上已经有了jdk1.1或以上版本),看到什么:

用法:jar {ctxu}[vfm0Mi] [jar-文件] [manifest-文件] [-C 目录] 文件名 ...

选项:

-c 创建新的存档

-t 列出存档内容的列表

-x 展开存档中的命名的(或所有的〕文件

-u 更新已存在的存档

-v 生成详细输出到标准输出上

-f 指定存档文件名

-m 包含来自标明文件的标明信息

-0 只存储方式;未用zip压缩格式

-M 不产生所有项的清单(manifest〕文件

-i 为指定的jar文件产生索引信息

-C 改变到指定的目录,并且包含下列文件:

如果一个文件名是一个目录,它将被递归处理。

清单(manifest〕文件名和存档文件名都需要被指定,按'm' 和 'f'标志指定的相同顺序。

示例1:将两个class文件存档到一个名为 'classes.jar' 的存档文件中:


jar cvf classes.jar Foo.class Bar.class

示例2:用一个存在的清单(manifest)文件 'mymanifest' 将 foo/ 目录下的所有文件存档到一个名为 'classes.jar' 的存档文件中:


jar cvfm classes.jar mymanifest -C foo/ .

来个小例子试试看:

我们只有一个HelloWorld,如下:


public class HelloWorld{
public static void main(String[ ] args){
System.out.println(“Hi, Hello World!”);
}
}

将这个java文件存到C盘跟目录下,ok,接下来,

在先前打开的命令提示符下(跳转到C盘提示符下),我们输入javac HelloWorld.java,然后继续输入:jar  cvf  hello.jar  HelloWorld.class,回车后去你的C盘看看,多了什么,没错 hello.jar 。

基本的步骤我们现在都知道了,你可以自己去尝试一下随着jar后面的参数的不同,结果有什么变化。
紧接着我们看看如何运行我们的jar包。

在进入正题之前,你要先打开我们刚刚做好的jar包看看,多了什么呢,META-INF目录?再看看里面是什么,还有一个MANIFEST.MF文件是不是?用文本编辑器(我这里是UltraEdit)打开它看看:


Manifest-Version: 1.0
Created-By: 1.4.2 (Sun Microsystems Inc.)

就是这样。这里我们对它进行修改,加一句:Main-Class: HelloWorld (在第三行)。这个就是我们之前写的那个类,也就是我们的入口类。也即,


Manifest-Version: 1.0
Created-By: 1.4.2 (Sun Microsystems Inc.)
Main-Class: HelloWorld

接下来,我们在命令提示符里执行:


jar  umf  MANIFEST.MF  app.jar (应该是hello.jar吧)

这样我们使用了我们自己的MANIFEST.MF文件对原来默认的进行了更新。你不妨可以再进去看看是不是添上了Main-Class: HelloWorld这一句。 (是吗,我怎么没试出来,提示java.io.FileNotFoundException:MANIFEST.MF(系统找不到指定的文件)怎么回 事?)

Ok,这个最后的一步了,来验证我们做的一切,在命令提示符中输入:


java -jar hello.jar(执行)

出现了什么, Hi, Hello World!

我们再来看看jar文件在tomcat中发布,注意:在tomcat中我们就不能再用jar这种格式,而改war格式,它是专门用于web应用的,其实整个过程下来基本上和jar是类似的:

先准备我们要打包的资源。

找到存放tomcat的webapps目录,进到其中,新建一个文件夹,这里命名为hello,再进去新建WEB-INF文件夹,再进去新建 classes文件夹,此时我们也将我们唯一的servlet,HelloWorld.java放到这里,在与classes目录同级下建立一文件 web.xml。Ok,目前我们初步建立了一个简单的web应用。

这是HelloWorld.java:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType(
"text/html");
PrintWriter out 
= res.getWriter();
out.println(
"");
out.println(
"");
out.println(
"");
out.println(
"Hello, World!");
out.println(
"");
}
}
//end here!
对它编译。下面是web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
</web-app>
在命令提示符下进到先前创制的hello目录下,执行 jar cvf hello.war * ,我们便得到hello.war。将它拷贝至webapps目录下,ok,来看最后一步,打开tomcat的目录conf中的server.xml,加入:

<Context path="/hello" docBase="hello.war" debug="0" reloadable="true"/>

大功告成!运行它,启动tomcat,后在浏览器中输入http://localhost:8080/hello/HelloWorld,有了吗?

最后,如果你想用ant来完成以上的打包活动,下面就告诉你:
对于jar来说。在build.xml中,


<target name="jar">
<jar destfile="${app_home}/hello.jar">
<fileset dir="${dest}" includes="**"/>
<!--fileset dir="${dest}" includes="**/action.properties"/-->
</jar>
</target>
对于war,


<war warfile="hello.war" webxml="./WEB-INF/web.xml">
<fileset dir="html"/>
<lib dir="lib/">
<exclude name="oracle*.jar"/>
</lib>
<classes dir="build/servlets">
<include name="**/*.class"/>
</classes>
</war>
好了,就这么多,希望对你有点帮助。:)

补充:

jar基本操作:

1. 创建jar文件

 



jar cf jar-file input-file(s)
c---want to Create a JAR file.
f---want the output to go to a file rather than to stdout.
eg: 1)jar cf myjar.jar query_maintain_insert.htm
2)jar cvf myjar.jar query_maintain_insert.htm
v---Produces verbose(详细的) output.


  3)jar cvf myjar.jar query_maintain_insert.htm mydirectory
4)jar cv0f myjar.jar query_maintain_insert.htm mydirectory
0---don't want the JAR file to be compressed.
5)jar cmf MANIFEST.MF myjar.jar yahh.txt
m---Used to include manifest information from an existing manifest file.
6)jar cMf MANIFEST.MF myjar.jar yahh.txt
M---the default manifest file should not be produced.
7)jar cvf myjar.jar *
*---create all contents in current directory. 

  2. 察看jar文件   

 


  jar tf jar-file
t---want to view the Table of contents of the JAR file.
eg: 1)jar vft yahh.jar
v---Produces verbose(详细的) output.  

  3. 提取jar文件  

 


  jar xf jar-file [archived-file(s)]
x---want to extract files from the JAR archive.
eg: 1)jar xf yahh.jar yahh.txt(仅提取文件yahh.txt)

  2)jar xf yahh.jar alex/yahhalex.txt(仅提取目录alex下的文件yahhalex.txt)  

  3)jar xf yahh.jar(提取该jar包中的所有文件或目录)  

  4. 修改Manifest文件  

 


  jar cmf manifest-addition jar-file input-file(s)
m---Used to include manifest information from an existing manifest file.  

  5. 更新jar文件  

 


  jar uf jar-file input-file(s)
u---want to update an existing JAR file.



文章来源:http://www.blogjava.net/supercrsky/articles/166271.html

posted @ 2009-04-10 13:20 天天开源 阅读(139) | 评论 (0)编辑 收藏

[导入]Java编译器对于String常量表达式的优化

 

首先把问题摆出来,先看这个代码

String a = "ab";
            String b = "a" + "b";
            System.out.println((a == b));

打印结果会是什么?类似这样的问题,有人考过我,我也拿来考过别人(蛮好玩的,大家也可以拿来问人玩),一般答案会是以下几种:

1.true

"a" + "b" 的结果就是"ab",这样a,b都是"ab"了,内容一样所以"相等",结果true

一般java新人如是答。

2.false

"a" + "a"会生成新的对象"aa",但是这个对象和String a = "ab";不同,(a == b)是比较对象引用,因此不相等,结果false

对java的String有一定了解的通常这样回答。

3.true

String a = "ab";创建了新的对象"ab"; 再执行String b = "a" + "b";结果b="ab",这里没有创建新的对象,而是从JVM字符串常量池中获取之前已经存在的"ab"对象。因此a,b具有对同一个string对象的引用,两个引用相等,结果true.

能回答出这个答案的,基本已经是高手了,对java中的string机制比较了解。

很遗憾,这个答案,是不够准确的。或者说,根本没有运行时计算b = "a" + "b";这个操作.实际上运行时只有String b = "ab";

3的观点适合解释以下情况:

String a = "ab";
            String b = "ab";
            System.out.println((a == b));

如果String b = "a" + "b";是在运行期执行,则3的观点是无法解释的。运行期的两个string相加,会产生新的对象的。(本文后面对此有解释)

4.true

下面是我的回答:编译优化+ 3的处理方式 = 最后的true

String b = "a" + "b";编译器将这个"a" + "b"作为常量表达式,在编译时进行优化,直接取结果"ab",这样这个问题退化

String a = "ab";
            String b = "ab";
            System.out.println((a == b));

然后根据3的解释,得到结果true

这里有一个疑问就是String不是基本类型,像

int secondsOfDay = 24 * 60 * 60;

这样的表达式是常量表达式,编译器在编译时直接计算容易理解,而"a" + "b" 这样的表达式,string是对象不是基本类型,编译器会把它当成常量表达式来优化吗?

下面简单证明我的推断,首先编译这个类:

public class Test {
            private String a = "aa";
            }

复制class文件备用,然后修改为

public class Test {
            private String a = "a" + "a";
            }

再次编译,用ue之类的文本编辑器打开,察看二进制内容,可以发现,两个class文件完全一致,连一个字节都不差.

ok,真相大白了.根本不存在运行期的处理String b = "a" + "b";这样的代码的问题,编译时就直接优化掉了。

下面进一步探讨,什么样的string + 表达式会被编译器当成常量表达式?

String b = "a" + "b";

这个String + String被正式是ok的,那么string + 基本类型呢?

String a = "a1";
            String b = "a" + 1;
            System.out.println((a == b)); //result = true
            String a = "atrue";
            String b = "a" + true;
            System.out.println((a == b)); //result = true
            String a = "a3.4";
            String b = "a" + 3.4;
            System.out.println((a == b)); //result = true

可见编译器对string + 基本类型是当成常量表达式直接求值来优化的。

再注意看这里的string都是"**"这样的,我们换成变量来试试:

String a = "ab";
            String bb = "b";
            String b = "a" + bb;
            System.out.println((a == b)); //result = false

这个好理解,"a" + bb中的bb是变量,不能进行优化。这里很很好的解释了为什么3的观点不正确,如果String+String的操作是在运行时进行的,则会产生新的对象,而不是直接从jvm的string池中获取。

再修改一下,把bb作为常量变量:

String a = "ab";
            final String bb = "b";
            String b = "a" + bb;
            System.out.println((a == b)); //result = true

竟然又是true,编译器的优化好厉害啊,呵呵,考虑下面这种情况:

String a = "ab";
            final String bb = getBB();
            String b = "a" + bb;
            System.out.println((a == b)); //result = false
            private static String getBB() {
            return "b";
            }

看来java(包括编译器和jvm)对string的优化,真的是到了极点了,string这个所谓的"对象",完全不可以看成一般的对象,java对string的处理近乎于基本类型,最大限度的优化了几乎能优化的地方。

另外感叹一下,string的+号处理,算是java语言里面唯一的一个"运算符重载"(接触过c++的人对这个不会陌生)吧?




文章来源:http://www.blogjava.net/supercrsky/articles/166463.html

posted @ 2009-04-10 13:20 天天开源 阅读(111) | 评论 (0)编辑 收藏

[导入]Java,误解为何如此之深

前几天被电话面试,问Java的参数传递方式,我说只有一种方式,就是by value啊,对方纠正我说,基本类型传值,对象类 型传引用;呜呼,当时被噎了一下,几秒钟后回过神来,我明白他的意思,也明白我碰上新世纪的新新人类了,但我怕他不明白啊,就说我们还是先把“引用”这个 概念定义清楚吧,不要同一个词两人有两个意思,或者举个例子吧,在函数里对String类型的参数赋值是不影响实际参数的啊,于是他也明白我其实也明白, 电话面试就算过了
然而还不算完,正式面试的四轮:笔试题,笔试完后与leader谈,谈完后与manager谈,谈完后与VP谈,居然每一轮都有这道题!只不过换成了swap函数的形式,让你说出执行结果;我就纳了闷了,这道题在人们心目中的形象就那么高大?并且甲方答案也似是而非?
Bjarne一直认为是C++的教育害了C++,那么是什么害了Java语言呢?过度的商业宣传!
当然,商业宣传成功的帮助了Java平台,吸引了大量开发者,但对Java语言来说,先听到宣传词后再来学习的初学者,耳中充斥的是“Java取消了指针”,“Java没有内存泄露”,“Java纯面向对象”等宣传用语,先入为主的就接受了表面现象,而没有理解问题的实质
Java 取消了指针?看看那个所谓的“引用”为空时抛出的异常吧,看看在Java实现者的眼中这个东西到底是啥吧:NullPointerException!不 是我鄙视Sun,它的细节伪装的确实不如MS:.Net里对应的异常叫NullReferenceException,虽然也是换汤不换药;作为一种类C语言,我认为对应概念的命名还是一致较好,Java里其实全是指针,你基本无法得到对象本身,只不过这种指针功能受限,不需删除而已
指针的概念被伪装起来,不需要delete了,那么除内存之外的其它资源呢?数数你的程序里有多少个finally就可以了
Java 纯面向对象?其实就这句话本身来说也无可厚非,只是它使用了<<箭鱼行动>>里定义的“错误引导”,这句话会使初学者倾向于认为 用Java写出来的程序都是面向对象的,从而阻碍了理解真正的面向对象;数数你程序里有多少根据对象类型的switch/if/else就可以了
题外话:
面试时被问道面向对象的三个基本特征,我知道他想听到什么封装继承多态,但实际上传统面向对象的核心特征就是多态,继承只是用来实现多态的一种手段,并非本质特征;C语言没有继承,但照样可以进行OO风格的编程



文章来源:http://www.blogjava.net/supercrsky/articles/166793.html

posted @ 2009-04-10 13:20 天天开源 阅读(58) | 评论 (0)编辑 收藏

[导入]Java泛型编程快速入门

     摘要: JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为5.0。这说明Java已经有大幅度的变化。本文将讲解JDK5.0支持的新功能-----Java的泛型. 1、Java泛型 其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可变的。而泛型也是一样...  阅读全文


文章来源:http://www.blogjava.net/supercrsky/articles/169570.html

posted @ 2009-04-10 13:20 天天开源 阅读(87) | 评论 (0)编辑 收藏

[导入]Static和Final修饰类属性变量及初始化

1.static修饰一个属性字段,那么这个属性字段将成为类本身的资源,public修饰为共有的,可以在类的外部通过test.a来访问此属性;在类内部任何地方可以使用.如果被修饰为private私有,那么只能在类内部使用.


 

public class Test{
public static int a;
private Test(){
a
=0;
}

}

 

 

如果属性被修饰为static静态类资源,那么这个字段永远只有一个,也就是说不管你new test()多少个类的对象,操作的永远都只是属于类的那一块内存资源.例如:


 

Test t1=new Test();
t1.a
=10;
Test t2
=new Test();
System.out.println(t1.a);
System.out.println(t2.a);
System.out.println(Test.a);

 

 

结果是3个0


2.final 用于声明属性,方法和类,分别表示属性一旦被分配内存空间就必须初始化并且以后不可变,方法一旦定义必须有实现代码并且子类里不可被覆盖,类一旦定义不能被定义为抽象类或是接口,因为不可被继承。


而你的代码里对final修饰的属性进行了修改,所以错误.


3. 被final修饰而没有被static修饰的类的属性变量只能在两种情况下初始化:


a.在它被定义的时候,例:

 

 

public class Test{
public final int a=0;
private Test(){
}

}

 

 

b.在构造函数里初始化,例:

 

 

public class Test{
public final int a;
private Test(){
a
=0;
}

}


 

 

4.同时被final和static修饰的类的属性变量只能在两种情况下初始化:


a.在它被定义的时候,例:

 

 

public class Test{
public final int a=0;
private Test(){
}

}


 

 

b.在类的静态块里初始化,例:

 

 

public class Test{
public final int a;
static{
a
=0;
}

}


 

 

5.分析第三第四原因:


第三条:当这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源,当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是定义了一个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时执行了构造函数,所以属性被初始化了,也就符合了当它被分配内存空间的时候就需要初始化,以后不再改变的条件.


第四条:当类的属性被同时被修饰为static和final的时候,他属于类的资源,那么就是类在被加载进内存的时候(也就是应用程序启动的时候)就要已经为此属性分配了内存,所以此时属性已经存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值.而构造函数是在当类被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化.程序就会报错.而static块是类被加载的时候执行,且只执行这一次,所以在static块中可以被初始化.

 




文章来源:http://www.blogjava.net/supercrsky/articles/169574.html

posted @ 2009-04-10 13:20 天天开源 阅读(104) | 评论 (0)编辑 收藏

[导入]用Java代码构建一个线程池

     摘要: 在现代的操作系统中,有一个很重要的概念――线程,几乎所有目前流行的操作系统都支持线程,线程来源于操作系统中进程的概念,进程有自己的虚拟地址空间以及正文段、数据段及堆栈,而且各自占有不同的系统资源(例如文件、环境变量等等)。与此不同,线程不能单独存在,它依附于进程,只能由进程派生。如果一个进程派生出了两个线程,那这两个线程共享此进程的全局变量和代码段,但每个线程各拥有各自的堆栈,因此它们拥有各自的局...  阅读全文


文章来源:http://www.blogjava.net/supercrsky/articles/169582.html

posted @ 2009-04-10 13:20 天天开源 阅读(63) | 评论 (0)编辑 收藏

[导入]Javadoc的简捷使用

J2SE5中的javadoc.exe的命令行可选参数多达五十余个,其复杂性可想而知,是不是看着头都大了呢?但通常情况下,我们不想那么麻烦!

假设源代码在 C:\src 目录下,其中 com.liigo 是主包,其下可能有数十个子包,数百(千)个Java文件。目录结构大约是这样的:

- C:\
    | src\
      | com\
        | liigo\

           | ***

怎么才能以最简捷的方式生成所有的API文档呢?

c:\>
c:\>cd src
c:\src>javadoc -d doc -subpackages com.liigo

这样就搞定了,最终生成的API文档位于 c:\src\doc 目录(该目录是由javadoc.exe自动生成的)。

上面的用法利用了“当前目录”和“相对路径”,当然也可以用绝对路径:

...>javadoc -d c:\doc -sourcepath c:\src -subpackages com.liigo

最终生成的API文档位于 c:\doc 目录(该目录同样是由javadoc.exe自动生成的)。


总结一下:

我们只用到了javadoc的三个参数: -d,-subpackages,-sourcepath,其中:

参数 说明
-d 指定API文档的输出目录,默认是当前目录。建议总是指定该参数。
-sourcepath 指定源代码路径,默认是当前目录。 此参数通常是必须的。
-subpackages 以递归的方式处理各子包。关键参数!如果不使用本参数,每次只能处理一个子包(或需手工列出所有子包)。


注:以上示例要求 javadoc.exe 所在路径位于系统环境变量“PATH”中。


补充一点:

使用参数 -author 可以将作者信息(@author ***)导出到最终生成的API文档中, -version 可以生成版本信息。如果是自己写的一个包,千万不要忘了用 -author 哦:)

最终完整的命令行是:

...>javadoc -d c:\doc -sourcepath c:\src -subpackages com.liigo -author -version

javadoc的命令行语法如下:

javadoc [ options ] [ packagenames ] [ sourcefiles ] [ @files ]

参数可以按照任意顺序排列。下面分别就这些参数和相关的一些内容进行说明:


  • Packagenames 包列表。这个选项可以是一系列的包名(用空格隔开),例如java.lang java.lang.reflect
    java.awt。不过,因为javadoc不递归作用于子包,不允许对包名使用通配符;所以你必须显示地列出希望建立文档的每一个包。
  • Sourcefiles 源文件列表。这个选项可以是一系列的源文件名(用空格隔开),可以使用通配符。javadoc允许四种源文件:类源代码文件、包描述文件、总体概述文件、其他杂文件。

    ◇ 类源代码文件:类或者接口的源代码文件。

    ◇ 包描述文件:每一个包都可以有自己的包描述文件。包描述文件的名称必须是"package.html",与包的.java文件放置在一起。包描述文件的内容通常是使用HTML标记写的文档。javadoc执行时将自动寻找包描述文件。如果找到,javadoc将首先对描述文件中<body></body>之间的内容进行处理,然后把处理结果放到该包的Package
    Summary页面中,最后把包描述文件的第一句(紧靠<body>)放到输出的Overview summary页面中,并在语句前面加上该包的包名。

    ◇ 总体概述文件:javadoc可以创建一个总体概述文件描述整个应用或者所有包。总体概述文件可以被任意命名,也可以放置到任意位置。-overview选项可以指示总体概述文件的路径和名称。总体概述文件的内容是使用HTML标记写的文档。javadoc在执行的时候,如果发现-overview选项,那么它将首先对文件中<body></body>之间的内容进行处理;然后把处理后的结果放到输出的Overview
    summary 页面的底部;最后把总体概述文件中的第一句放到输出的Overview summary页面的顶部。

    ◇ 其他杂文件:这些文件通常是指与javadoc输出的HTML文件相关的一些图片文件、Java源代码文件(.java)、Java程序(.class)、Java小程序(Applets)、HTML文件。这些文件必须放在doc-files目录中。每一个包都可以有自己的doc-files目录。举个例子,你希望在java.awt.Button的HTML文档中使用一幅按钮的图片(Button.gif)。首先,你必须把图片文件放到C:\user\src\java\awt\doc-files\中;然后在Button.java文件中加入下面注释

    /**

    * This button looks like this:

    * <img src="doc-files/Button.gif">

    */
  • @files 包含文件。为了简化javadoc命令,你可以把需要建立文档的文件名和包名放在一个或多个文本文件中。例如,为了简化下面命令:

    javadoc -d apidoc com.mypackage1 com.mypackage2 com.mypackage3

    你可以建立一个名称为mypackage.txt的文件,其内容如下:

    com.mypackage1

    com.mypackage2

    com.mypackage3

    然后执行下面命令即可:

    javadoc -d apidoc @mypackage.txt

  • options 命令行选项。javadoc使用doclets(doclets是指用doclet API编写的程序。)来确定输出的内容和格式。命令行选项中一部分是可用于所有doclet的通用选项,一部分是由默认的标准doclet提供的专用的选项。下面对各自一些常用的选项分别进行介绍:

    通用选项:

    -1.1 生成具有javadoc 1.1版本生成的文档的外观和功能的文档。不是所有的选项都可以用于-1.1选项,具体可以使用javadoc
    -1.1 -help察看。

    -help 显示联机帮助。

    -bootclasspath classpathlist 指定"根类"(通常是Java平台自带的一些类。例如java.awt.*等)的路径。

    -sourcepath sourcepathlist 指定包的源文件搜索路径。但是必须注意,只有在javadoc命令中指定了包名的时候才可以使用-sourcepath选项。如果指定了包名,而省略了-sourcepath,那么javadoc使用类路径查找源文件。举例说明:假定你打算为com.mypackage建立文档,其源文件的位置是C:\user\src。那么你可以使用下面的命令:

    javadoc -sourcepath c:\user\src com.mypackage

    -classpath classpathlist 指定javadoc查找"引用类"的路径。引用类是指带文档的类加上它们引用的任何类。javadoc将搜索指定路径的所有子目录。Classpathlist可以包含多个路径(使用;隔开)。如果省略-classpath,则javadoc使用-sourcepath查找源文件和类文件。举例说明:假定你打算为com.mypackage建立文档,其源文件的位置是C:\user\src,包依赖C:\user\lib中的库。那么你可以使用下面的命令:

    javadoc -classpath c:\user\lib -sourcepath c:\user\src com.mypackage

    -overview path\filename 告诉javadoc从path\filename所指定的文件中获取概述文档,并且把它放到输出的概述页面(overview-summary.html)中。其中path\filename是相对于-sourcepath的相对路径。

    -public 只显示公共类以及成员。

    -protected 只显示受保护的和公共的类以及成员。缺省选项。

    -package只显示包、受保护的和公共的类以及成员。

    -private 显示所有类和成员。

    -doclet class 指定javadoc产生输出内容的自定义doclet类。如果忽略这个选项,javadoc将使用默认的doclet产生一系列HTML文档。

    -docletpath classpathlist 与- doclet选项相关,制定自定义的doclet类文件的路径。Classpathlist可以包含多条路径(用;隔开)。

    -verbose 在javadoc运行时提供更详细的信息。

    标准doclet专用选项:

    -author 在生成的文档中包含"作者"项。

    - d directory 指定javadoc保存生成的HTML文件的目录。省略该选项将把文件保存在当前目录。Directory可以是绝对目录,也可以是相对当前目录的相对目录。

    -version 在生成的文档中包含"版本"项。

    -use 为类和包生成"use"(用法)页面。这些页面描述了该类和包在javadoc命令涉及的文件中被使用的情况。例如:对于给定的类C,在C的用法页面中将包含C的子类,类型为C的域,返回变量类型为C的方法以及在参数中有变量类型为C的方法和构造器。

    -splitindex 把索引文件按照字母顺序分为多个文件。每一个文件对应一个字母。

    -windowtitle title 指定输出的HTML文档的标题。

    -header header 指定输出的HTML文档的页眉文本。

    -footer footer 指定输出的HTML文档的脚注文本。

    -bottom text 指定输出的HTML文档底部的文本。

    - group groupheading packagepatten;packagepatten;… 在总体概述页面中按照命令的指定方式分隔各个包。例如执行下面命令:

    javadoc -group "Core Packages" "java.lang*:java.util"

    -group "Extension Packages" "javax.*"

    java.lang java.lang.reflect java.util javax.servlet java.new

    在页面中将有如下结果:

    Core Packages

    java.lang

    java.lang.reflect

    java.util

    Extension Packages

    javax.servlet

    Other Packages

    java.new

    ◇ - noindex 不输出索引文件。

    ◇ - help 在文件的导航条中忽略help链接。

    ◇ - helpfile path\filename 指定导航条中的help链接所指向的帮助文件。忽略该选项,javadoc将生成缺省的帮助文件。

    ◇ -stylesheetfile path\filename 指定javadoc的HTML样式表文件的路径。忽略该选项,javadoc将自动产生一个样式表文件stylesheet.css。

    通过上面的介绍,我们了解了javadoc的命令行语法,下面开始介绍javadoc文档注释方法。

    javadoc注释以"/**"开始,以"*/"结束,里面可以包含普通文本、HTML标记和javadoc标记。javadoc只处理源文件中在类/接口定义、方法、域、构造器之前的注释,忽略位于其他地方的注释。举例如下:
    /**

    *我的第一个程序--<b>Helloworld</b>

    *@author 王鸿

    *@version 1.0 2001/10/15

    */

    public class myHelloworld

    {

    /**

    *在main( )方法中使用的显示用字符串

    *@see #main(java.lang.String[])

    */

    static String SDisp

    使用下面命令:

    javadoc -private -d doc -author -version myHelloworld.java

    即可以生成漂亮的关于myHelloworld.java的API文档了。

    上面例子中以@开头的标记就是javadoc标记。在Java程序中正确使用javadoc标记是一个良好的注释习惯,将非常有助于javadoc自动从源代码文件生成完整的格式化API文档。下面就对各种标记进行详细说明。

    @author name-text 指定生成文档中的"作者"项,从JDK/SDK 1.0开始引入。name-text可以指定多个名字(使用","隔开)。文档注释可以包含多个类。

    {@docroot} 代表产生文档的根路径,从JDK/SDK 1.3开始引入。用法举例如下

    /**

    *see the <a href={@docroot}/copyright.html>copyright</a>

    */

    假定生成文档的根目录是doc,上面注释所在的文件最后生成的文件是doc\utility\utl.html,那么"copyright"的链接会指向..\copyright.html。

    @deprecated deprecated-text 添加注释,表明不推荐使用该API。

    @exception class-name description @throw的同义标记,从JDK/SDK 1.0开始引入。

    {@link package.class#member label} 插入指向package.class#member的内嵌链接,从JDK/SDK
    1.2开始引入。举例说明,假定注释中有如下文档:

    /** Use the {@link #getComponentAt(int, int) getComponentAt} method. */

    那么javadoc最终生成的HTML页面中将有如下内容

    Use the <a href = "Component.html#getComponentAt(int,int)"
    > getComponentAt </a> method.

    @param parameter-name description 描述参数,从JDK/SDK 1.0开始引入。

    @return description 描述返回值,从JDK/SDK 1.0开始引入。

    @see reference 添加"参见"标题,其中有指向reference的链接或者文本项,从JDK/SDK
    1.0开始引入。@see标记有三种形式,下面分别说明:

    (1)、@see "string" 为"string"添加文本项,不产生链接。

    (2)、@see <a href="URL#Value">Label</a> 使用HTML标记产生链接

    (3)、@see package.class#member Label 使用Java语言的名字package.class #member产生链接。

    ◇ @serial field-description 用于缺省可序列化域的注释,从JDK/SDK 1.2开始引入。

    ◇ @serialField field-name field-type field-description 建立Serializable类的serialPersistentFields成员的ObjectStreamField组件的文档,从JDK/SDK
    1.2开始引入。

    @serialData data-description data-description建立数据序列和类型的文档,从JDK/SDK
    1.2开始引入。

    @since since-text 利用since-text内容为文档增加"since"标题,从JDK/SDK
    1.1开始引入。

    @throws class-name description 与@exception同义。用class-name和description为输出文档添加"抛出"标题,从JDK/SDK
    1.2开始引入。

    @version version-text 添加"版权"标题,从JDK/SDK 1.0开始引入。

    上面介绍了标准doclet提供的所有标记。不过,需要注意这些标记的使用是有位置限制的。其中可以出现在类或者接口文档注释中的标记有:@see、{@link}、@since、@deprecated、@author、@version。可以出现在方法或者构造器文档注释中的标记有:@see、{@link}、@since、@deprecated、@param、@return、@throws、@exception、@serialData。可以出现在域文档注释中的有:@see、{@link}、@since、@desprecated、@serial、@serialField。

    除了javadoc自身提供的标准标记以外,我们可以定制自己的标记吗?当然可以。只需要对javadoc标准的doclet程序进行扩充即可。实际上,利用javadoc提供的doclet
    API,不仅可以扩充doclet标记,甚至还可以改变javadoc的整个输出。为了满足需要,你可以使javadoc输出普通文本、XML文件等。由于扩充doclet涉及到Java编程,本文不再做深入介绍。

    总之,javadoc提供了完整规范的API文档功能。在软件项目管理中,合理地使用javadoc不仅可以减少
    开发时的文档工作量,提高效率;而且还非常有利于将来软件的修改和维护。





文章来源:http://www.blogjava.net/supercrsky/articles/172385.html

posted @ 2009-04-10 13:20 天天开源 阅读(243) | 评论 (0)编辑 收藏

[导入]throws和throw的区别

这两者虽然看起来只有一个s的区别,但是作用完全不一样。
                                                                                   
/////java处理异常方式///////////////////////////////

     在java代码中如果发生异常的话,jvm会抛出异常对象,导致程序代码中断,这个时候jvm在做的操作就是:创建异常对象,然后抛出,比如:

 

int i= 1; 
int j = 0
; 
int res = 0
; 
res 
= i/j;//除0错误 

System.out.println(res); 

 

这5句代码运行到第四句会中断,因为jvm抛出了异常
 
////throw的作用/////////////////////////////////////////
手动抛出异常

但是有时候有些错误在jvm看来不是错误,比如说

int age = 0
age 
= -100

System.out.println(age); 

 

    很正常的整形变量赋值,但是在我们眼中看来就不正常,谁的年龄会是负的呢。 所以我们需要自己手动引发异常,这就是throw的作用。

int age = 0
age 
= -100

if(age<0


   Exception e 
= new Exception("throw exception");//创建异常对象 

   throw e;//抛出异常 
}
 
System.out.println(age); 

 

////throws的作用///////////////////////////////////
声明方法可能回避的异常

   有异常被抛出了,就要做处理,所以java中有try-catch。可是有时候一个方法中产生了异常,但是不知道该怎么处理它,那么就放着不管,当有异常抛出时会中断该方法,而异常被抛到这个方法的调用者那里。这个有点像下属处理不了的问题就交到上司手里一样,这种情况称为回避异常。

   但是这使得调用这个方法就有了危险,因为谁也不知道这个方法什么时候会丢一个什么样的异常给调用者,所以在定义方法时,就需要在方法头部分使用throws来声明这个方法可能回避的异常。

void fun()throws IOException,SQLException 

 
}
 

 

这表示 fun方法可能会丢两个异常出来,那么在调用fun的时候就会做好准备,比如可以这样

try
   fun(); 
}
catch(IOException e) { }

catch(SQLException e) { } 

 

 




文章来源:http://www.blogjava.net/supercrsky/articles/176511.html

posted @ 2009-04-10 13:20 天天开源 阅读(101) | 评论 (0)编辑 收藏

[导入]Eclipse和MyEclipse工程描述符详解

   有时候在一个Java工程里我们需要加入第三方jar包,这时你加入的最好相对路径,
而不是绝对路径。否则你的工程拿到别处就不行运行了。意思就是说你最好把相关的jar放到工程目录下。对于Web工程来说相对简单,web工程是有个lib 目录的。直接复制到这里就行了。而非web工程是不可以的。Eclispe是不能自动完成导入copy的。
这就需要我们手动配置,对于工作描述文件,Eclipse和MyEclpse全是用xml来描述的。

现在我们来看看Eclipse的.classpath文件:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    
<!-- 源码目录 -->
    
<classpathentry kind="src" path="src"/>
    
<!-- JDK运行时容器 -->
    
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    
<!-- 以下为类库 path为你自定义的目录 -->
    
<classpathentry kind="lib" path="lib/swing-layout-1.0.3.jar"/>
    
<classpathentry kind="lib" path="lib/AbsoluteLayout.jar"/>
    
<classpathentry kind="lib" path="lib/jtds-1.2.2.jar"/>
    
<classpathentry kind="lib" path="lib/jxl.jar"/>
    
<!-- 编译后输出class 目录  -->
    
<classpathentry kind="output" path="bin"/>
</classpath>


在xml中我已经加了注释。想你也明白了吧。

.project文件:
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    
<!-- 工程名称 -->
    
<name>execlInterface</name>
    
<comment></comment>
    
<projects></projects>
    
<!-- 编译器指定 -->
    
<buildSpec>
        
<buildCommand>
            
<name>org.eclipse.jdt.core.javabuilder</name>
            
<arguments></arguments>
        
</buildCommand>
    
</buildSpec>
    
<!-- 核心特性 -->
    
<natures>
        
<nature>org.eclipse.jdt.core.javanature</nature>
    
</natures>
</projectDescription>


对于myeclipse工程多了一个.mymetadata文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 
    type : 工程类型
    name : 工程名称
    id   : 工程在工作空间内的唯一标识
    context-root : 网站根路径
    j2ee-spec: J2EE标准
    archive : 打包后war文件
 
-->

<project-module
  
type="WEB"
  name
="upload"
  id
="myeclipse.1152954865843"
  context-root
="/upload"
  j2ee-spec
="1.4"
  archive
="upload.war">
  
<attributes>
  
<!-- value : Web根目录名称 -->
    
<attribute name="webrootdir" value="WebRoot" />
  
</attributes>
</project-module>




文章来源:http://www.blogjava.net/supercrsky/articles/204013.html

posted @ 2009-04-10 13:20 天天开源 阅读(857) | 评论 (0)编辑 收藏

仅列出标题
共2页: 上一页 1 2