• 网志分类
  • » 查看所有日志 (52)
    » 数据库技术 (7)
    » UNIX&linux&(!windows) (16)
    » c/c++ (6)
    » java技术 (10)
    » perl (2)
    » 嵌入式应用 (0)
    » 管理理念 (2)
    » 理财理念 (2)
    » 联系我 (1)
    » 随便写写吧 (1)
    » 人生哲理 (3)
    » 被遗忘的角落 (2)
  • 最新评论
  • 站内搜索
  • 友情链接
  • » 我的歪酷 非非共享界
    » 开放软件测试研究

    订阅 RSS

    歪酷博客

    0016721

    mars @ 2005-12-15 16:59



     
    mars @ 2005-12-15 16:54

    我在Fedora Core 3上已经成功安装了jdk(jdk-1_5_0_02-linux-i586.rpm),其它版本的Linux基本相同,过程如下:

    1. 先从网上下载jdk(jdk-1_5_0_02-linux-i586.rpm) ,推荐SUN的官方网站www.sun.com,下载后放在/home目录中,当然其它地方也行。

    进入安装目录
    #cd /home
    #cp jdk-1_5_0_02-linux-i586.rpm /usr/local
    #cd /usr/local
    给所有用户添加可执行的权限
    #chmod +x jdk-1_5_0_02-linux-i586.rpm.bin
    #./jdk-1_5_0_02-linux-i586.rpm.bin
    此时会生成文件jdk-1_5_0_02-linux-i586.rpm,同样给所有用户添加可执行的权限
    #chmod +x jdk-1_5_0_02-linux-i586.rpm
    安装程序
    #rpm -ivh jdk-1_5_0_02-linux-i586.rpm


     
    mars @ 2005-10-19 10:48

    Helloworld功略
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=84

    path和classpath
    1.什么是java的path和classpath?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=904
    2.如何一次把一个目录下的所有.jar加入到classpath?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=905
    3.classspath 的默认值是什么?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=906
    4.怎样找到程序运行需要的类?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=907
    5. Linux下Path和ClassPath是怎么设的?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=908
    6.如何修改path和classpath?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=909

    java的帮助和api文档
    1.什么是java的api参考?
    api是html格式的从sun的网站上可以找到一个包
    包括api的参考和user guide,本站有做成.chm格式的便于查找。
    api参考是用jdk的工具javadoc 生成的是开发者必备的文档。
    2.哪里有JAVA基本类库的源代码?
    jdk的安装目录下有源码src.zip
    3.java web start 是干什么用的?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=911

    开发环境
    1.jre下的lib和jdk下的lib到底有什么区别?
    jre是JDK的一个子集。提供一个运行环境。JDK的lib目录是给JDK用的,例如JDK下有一些工具,可能要用该目录中的文件。例如,编译器等。JRE的lib目录是为JVM,运行时候用的。包括所有的标准类苦,和扩展类
    2.我的jbuilder光标对不齐?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=913
    3.JDK版本冲突怎么办?
    要决定windows使用哪一个JDK(win2000),改注册表:
    HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\CurrentVersion
    的值,要决定JBuilder使用哪个JDK在project properties中可以设置。
    4.editplus能够编译java嘛? 如何设置?
       先要将JAVA的运行环境安装并且调试好。
       首先,从菜单“工具(Tools)”->“配置用户工具...”进入用户工具设置。
       在类别里展开“工具”树形菜单->“用户工具”,选择“组和工具项目”中的“Group 1”,点击面板右边的“组名称...”按钮,将文本“Group1”修改成“编译JAVA程序”。
       然后选择修改的组“编译JAVA程序”,点击“添加新工具”按钮,选择程序,建立“新建程序”,选中它。
       然后就是最重要的步骤(修改属性):
       1.1 添加编译功能
       “菜单文字”里的内容修改为“JAVAC”;
       “命令”选择安装JDK后的BIN目录中的编译程序JAVAC.EXE,如果JDK 安装路径为“c:\jdk”,那么此路径为“c:\jdk\bin\javac.exe”;
       “参数”选择“文件名称”,即显示为“$(FileName)”;
       “初始目录”选择“文件目录”,显示为“$(FileDir)”;
       选择“捕获输出”复选框。
       1.2 添加执行功能
       “菜单文字”里的内容修改为“JAVA”;
       “命令”选择安装JDK后的BIN目录中的编译程序JAVA.EXE,路径为“c:\jdk\bin\java.exe”;
       “参数”选择“文件名(不含扩展名)”,即显示为“$(FileNameNoExt)”;
       “初始目录”选择“文件目录”,显示为“$(FileDir)”;
       选择“捕获输出”复选框。
       这样就完成了基本的配置工作

    基础概念
    1.public,private,protect的访问机制

    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=914
    2.Java中如何定义一个常量?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=915
    3.异常的throw和throws有什么区别
    throw是在程序中抛出异常,而throws是在方法的声明中声明抛出异常
    4.upcasting是什么意思
    upcasting就是上溯.也就是说把一个子类当作它的父类看待,比如:对方法void do(Object obj){...},你可以把任何对象作为参数来调用.

    编译运行
    1.怎么把多个.java源文件编译成一个.class?
    java -d . a.java b.java
    2. depreciated API 是什么意思?
    java发展太快,所以你应该尽可能用最新的api,但是老的api还是兼容的,所以回waning 你deprecated api
    3.怎么样编译一个目录下的所有java文件?
    ant或者jbuilder,或者自己写脚本.
    4.如何让执行程序时不会出现dos窗口?
    javaw
    5.如何运行jar文件?
    java -jar ***.jar
    6.如何去掉JAVA的内存限制
    加 -Xmx参数来设置maximum Java heap size,如: java -Xms10M MyClass
    7.什么是Java混淆编译器?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=916
    8.如何将Java应用程序本地编译为EXE?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=917
    9.jar命令?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=918

    数据类型与转换
    1.int、char、double与byte如何相互转换?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=919
    2.int与byte array之间的转换程序?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=920
    3.string和int之间的转换?
    a1=Integer.parseInt(s1);
    s1=Integer.toString(a1);
    4.java如何获得随机整数?
    首先利用random()获得一个随机浮点数,然后乘以你希望得到的整数
    的最大值,最后对得到的结果取整。
    5.怎么把String类型转换成16进制的整数?
    public static void main(String args[]){
           String x = "0x300C8";
           int y = Integer.decode(x).intValue();
           System.out.println(y);
       }
    6.int和java.lang.Integer有和区别?
    int是数据类型,Integer是类Integer的功能更强,可以将整数转换为浮点数运算,在java这种强类型语言中是很有用的。可以利用Integer的构造函数Integer(int)来对一个整数建立对象。类似的类还有Float,Short,Long等等

    数据结构
    1.如何实现二维向量?
    Vector vector1=new Vector();
    Vector vector2=new Vector();
    ...
    ..
    HashTable numbers=new HashTable();
    numbers.put("vector1",vector1);
    numbers.put("vector2",vector2);
    2. JAVA中怎么得到现在的系统时间?
    比如,当前date,Date today=new Date(System.currentTimeMillis());
    3.如何将java.util.Date转化为java.sql.Date?
    转化:

    java.sql.Date sd;
    java.util.Date ud;
    //initialize the ud such as ud = new java.util.Date();

    sd = new java.sql.Date(ud.getTime());

    如果要插入到数据库并且相应的字段为Date类型
    那么可以用PreparedStatement.setDate(int ,java.sql.Date)方法
    其中的java.sql.Date可以用上面的方法得到

    也可以用数据库提供TO_DATE函数
    比如 现有 ud
    TO_DATE(new SimpleDateFormat().format(ud,"yyyy-MM-dd HH:mm:ss"),
    "YYYY-MM-DD HH24:MI:SS")
    注意java中表示格式和数据库提供的格式的不同

    系统相关
    1.在JAVA中如何启动一个程序?
    String strCommand;
    String cmd = "cmd";
    if (! System.getProperty("os.name").equals("Windows NT")) cmd = "command";
    cmd = cmd + " /c " + strCommand;
    try {
           Runtime.getRuntime().exec(cmd);
    }
    catch (IOException ex) {
    }

    strCommand 为命令串,DOS 底下怎么用,这儿就可以怎么用
    2.如何得到应用程序的路径
    Properties System.getProperties()里面有
    3.如何得到当前系统时间?
      1.SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd");
         String time=formatter.format(new Date());
       2.Calendar cal = Calendar.getInstance();
           int year = cal.get(Calendar.YEAR);
            month=..类推


    输入输出
    1.是否可以用纯JAVA 编写程序来访问串口?
    Sun提供了一个叫javax.comm的package,专门用来对serial port进行操作.
    2.writeutf和write的区别
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=921
    3.如何利用FileWriter在文本中换行?
    \r\n

    网络相关
    1.如何让我的程序通过proxy访问外部网络?
    System.setProperty("java.proxyHost","your proxy here");

    本地相关
    1.如何调用本地的dll?
     jni
    2.如何用java编写扫描仪程序?
    http://www.matrix.org.cn/forum_view.asp?forum_id=19&view_id=2741




     
    mars @ 2005-09-27 20:46

      

    最古老的解决方案是使用String的字节码转换,这种方案问题是不方便,我们需要破坏对象封装性,进行字节码转换。

      还有一种方式是对J2EE容器进行编码设置,如果J2EE应用系统脱离该容器,则会发生乱码,而且指定容器配置不符合J2EE应用和容器分离的原则。

      在Java内部运算中,涉及到的所有字符串都会被转化为UTF-8编码来进行运算。那么,在被Java转化之前,字符串是什么样的字符集? Java总是根据操作系统的默认编码字符集来决定字符串的初始编码,而且Java系统的输入和输出的都是采取操作系统的默认编码。

      因此,如果能统一Java系统的输入、输出和操作系统3者的编码字符集合,将能够使Java系统正确处理和显示汉字。这是处理Java系统汉字的一个原则,但是在实际项目中,能够正确抓住和控制住Java系统的输入和输出部分是比较难的。J2EE中,由于涉及到外部浏览器和数据库等,所以中文问题乱码显得非常突出。

      J2EE应用程序是运行在J2EE容器中。在这个系统中,输入途径有很多种:一种是通过页面表单打包成请求(request)发往服务器的;第二种是通过数据库读入;还有第3种输入比较复杂,JSP在第一次运行时总是被编译成Servlet,JSP中常常包含中文字符,那么编译使用javac时,Java将根据默认的操作系统编码作为初始编码。除非特别指定,如在Jbuilder/eclipse中可以指定默认的字符集。
    输出途径也有几种:第一种是JSP页面的输出。由于JSP页面已经被编译成Servlet,那么在输出时,也将根据操作系统的默认编码来选择输出编码,除非指定输出编码方式;还有输出途径是数据库,将字符串输出到数据库。

      由此看来,一个J2EE系统的输入输出是非常复杂,而且是动态变化的,而Java是跨平台运行的,在实际编译和运行中,都可能涉及到不同的操作系统,如果任由Java自由根据操作系统来决定输入输出的编码字符集,这将不可控制地出现乱码。

      正是由于Java的跨平台特性,使得字符集问题必须由具体系统来统一解决,所以在一个Java应用系统中,解决中文乱码的根本办法是明确指定整个应用系统统一字符集。

      指定统一字符集时,到底是指定ISO8859_1 、GBK还是UTF-8呢?

      (1)如统一指定为ISO8859_1,因为目前大多数软件都是西方人编制的,他们默认的字符集就是ISO8859_1,包括操作系统Linux和数据库MySQL等。这样,如果指定Jive统一编码为ISO8859_1,那么就有下面3个环节必须把握:

      开发和编译代码时指定字符集为ISO8859_1。

      运行操作系统的默认编码必须是ISO8859_1,如Linux。

      在JSP头部声明: <%@ page contentType="text/html;charset=ISO8859_1" %>。

      (2)如果统一指定为GBK中文字符集,上述3个环节同样需要做到,不同的是只能运行在默认编码为GBK的操作系统,如中文Windows。

      统一编码为ISO8859_1和GBK虽然带来编制代码的方便,但是各自只能在相应的操作系统上运行。但是也破坏了Java跨平台运行的优越性,只在一定范围内行得通。例如,为了使得GBK编码在linux上运行,设置Linux编码为GBK。

      那么有没有一种除了应用系统以外不需要进行任何附加设置的中文编码根本解决方案呢?

      将Java/J2EE系统的统一编码定义为UTF-8。UTF-8编码是一种兼容所有语言的编码方式,惟一比较麻烦的就是要找到应用系统的所有出入口,然后使用UTF-8去“结扎”它。
     一个J2EE应用系统需要做下列几步工作:

      开发和编译代码时指定字符集为UTF-8。JBuilder和Eclipse都可以在项目属性中设置。

      使用过滤器,如果所有请求都经过一个Servlet控制分配器,那么使用Servlet的filter执行语句,将所有来自浏览器的请求(request)转换为UTF-8,因为浏览器发过来的请求包根据浏览器所在的操作系统编码,可能是各种形式编码。关键一句:



    request.setCharacterEncoding("UTF-8")
      网上有此filter的源码。
      在JSP头部声明:
    <%@ page contentType="text/html;charset= UTF-8" %>
      在Jsp的html代码中,声明UTF-8:
    <META http-equiv="Content-Type" CONTET="text/html; charset=utf-8">
      设定数据库连接方式是UTF-8。例如连接MYSQL时配置URL如下:
    jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
      一般数据库都可以通过管理设置设定UTF-8。

      其他和外界交互时能够设定编码时就设定UTF-8,例如读取文件,操作XML等。

      笔者以前在Jsp/Servlet时就采取这个原则,后来使用Struts、Tapestry、EJB、Hibernate、Jdon等框架时,从未被乱码困扰过,可以说适合各种架构。希望本方案供更多初学者分享,减少Java/J2EE的第一个拦路虎,也避免因为采取一些临时解决方案,导致中文问题一直出现在新的技术架构中。





     
    mars @ 2005-09-17 12:07

    代号为“猛虎”(Tiger)的J2SE 1.5计划于今年晚些时候发布。对于这个万众瞩目的新版本,
    没有比Joshua Bloch 更适合来介绍它的了。在一次问答式的访谈中,这位卡内基-梅隆大学的
    计算机博士、Java Collection 框架的设计者、畅销书Effective Java 的作者、Java 开发者的
    “教父”详细地介绍了J2SE 1.5的6 大新特性??这篇访谈中充斥着大量的代码,我很想知道
    这位作者是如何采访Bloch 先生的J
    Joshua Bloch 表示,J2SE 1.5的核心设计思想就是简化开发者的工作,将重复性的编码工作
    交给编译器,使代码更整洁、更简练、更坚固、更可维护。由于Java 日益成为一种服务器端应
    用程序开发的语言,因此效率在很大程度上已经不是它最着重考虑的方面。J2SE 1.5 有6 项最
    主要的新特性:
    &Oslash; 泛型
    &Oslash; 增强的for 循环
    &Oslash; 自动装箱/拆箱
    &Oslash; 类型安全的枚举
    &Oslash; 静态导入
    &Oslash; 元数据
    下面,我们分别来了解这6 项新特性。
    泛型(generics)
    基于JSR 14 的泛型Java 已经受到了很多的关注。侯捷先生去年就曾在专栏文章中介绍泛型
    Java 的实现和使用。在Java 中,泛型主要应用在容器(collection)数据类型。它可以使容器
    具有类型安全性,并且避免了在读取容器所容纳的元素时进行强制类型转换。例如,下列代码:
    /**
    * Remove the four-letter words from the specified
    * collection, which must contain only strings.
    */
    static void expurgate(Collection c) {
    for (Iterator i = c.iterator(); i.hasNext(); ) {
    String s = (String) i.next();
    if(s.length() == 4)
    i.remove();
    }
    }
    在使用泛型容器之后将变成这样:
    /**
    * Remove the four-letter words from the specified collection of strings.
    */
    static void expurgate(Collection<String> c) {
    for (Iterator<String> i = c.iterator(); i.hasNext(); )
    if (i.next().length() == 4)
    i.remove();
    }
    容器c 对装入其中的对象类型有了强制,因此在用iterator 取出元素时也就无须再进行一次类
    型转换,代码显得更加清爽。
    由于Java 拥有数以百万计的用户,Sun 不可能为了加入泛型机制而要求所有用户更换新的虚拟
    机。因此,Java 将采用比较温和的“擦拭法”实现泛型,也就是说,在进行类型检查之后,即
    将对象的具体类型信息擦去,从而与原来的非泛型容器对接。显然,使用这种方式实现的泛型容
    器将没有任何效率上的优势。与.NET 1.1 提供的强大的泛型机制相比,泛型Java 只是提高了
    代码的质量而已??这也和Joshua Bloch 反复强调的“以开发者为本”的精神相吻合。
    增强的for 循环(enhanced for loop)
    所谓“增强的for 循环”,主要也是针对容器的。使用该项特性时,开发者可以将“利用iterator
    遍历容器”的逻辑交给编译器来处理。例如下列代码:
    void cancelAll(Collection c) {
    for (Iterator i = c.iterator(); i.hasNext(); ) {
    TimerTask tt = (TimerTask) i.next();
    tt.cancel();
    }
    }
    可以用增强的for 循环改写为:
    void cancelAll(Collection c) {
    for (Object o : c)
    ((TimerTask)o).close();
    }
    编译器判断对象c 是一个Collection 子对象(即是容器)之后,就会允许使用增强的for 循环
    形式,并自动取到c 的迭代器,自动遍历c 中的每个元素。
    可以看到,上面的代码中仍然有一个强制类型转换(((TimerTask)o).close();)。实际上,这
    项特性应该普遍地与泛型结合,以获得最大的利益。结合泛型之后,上述代码变成:
    void cancelAll(Collection<TimerTask> c) {
    for (TimerTask task : c)
    task.cancel();
    }
    自动装箱/拆箱(auto-boxing/unboxing)
    Java 有一个“分裂的类型系统”(split type system),区分原生类型(primitive type,例如
    int、char)和非原生类型(non-primitive type,例如类、枚举)。到目前为止,不能把原生
    类型放入容器之中,必须首先将其转换成对应的非原生类型(例如int 对应的非原生类型就是
    Integer)。自动装箱就是用于帮助处理这项工作的,自动拆箱则是自动装箱的逆过程,将非原
    生类型转换为对应的原生类型。
    下列代码的功能是生成命令行中词汇出现的频率表:
    public class Freq {
    private static final Integer ONE = new Integer(1);
    public static void main(String args[]) {
    // Maps word (String) to frequency (Integer)
    Map m = new TreeMap();
    for (int i=0; i<args.length; i++) {
    Integer freq = (Integer) m.get(args);
    m.put(args, (freq==null ? ONE :
    new Integer(freq.intValue() + 1)));
    }
    System.out.println(m);
    }
    }
    可以看到,Map 容器中只能容纳Integer 对象。因此,为了将一个整数值加1 再放入容器,就
    必须使用new Integer(freq.intValue() + 1)这样麻烦的一个语句。在使用自动装箱(以及
    泛型)之后,上述代码变成:
    public class Freq {
    public static void main(String args[]) {
    Map<String, Integer> m = new TreeMap<String, Integer>();
    for (String word : args)
    m.put(word, m.get(word) + 1);
    System.out.println(m);
    }
    }
    代码总量减少了将近一半。
    另外,如果你对null 进行拆箱,将会得到0。但是,这个结果目前尚未最后确定,也有人认为
    对null 的拆箱操作应该抛出NullPointerException。目前,JSR 201 专家组仍在讨论应该采
    用哪种方案。
    类型安全的枚举(typesafe enum)
    在Effective Java 一书中,Joshua Bloch 曾经介绍过类型安全的枚举的优点,并提出了一个
    名为“Type Safety Enum”的模式(条款21)。在J2SE 1.5中将加入这一新特性。比起传统
    的int 枚举,类型安全的枚举有如下优点:
    &Oslash; 提供了编译器类型安全;
    &Oslash; 为枚举类型提供了合适的名字空间;
    &Oslash; 更加坚固可靠;
    &Oslash; 输出的枚举值将带有更多的信息;
    &Oslash; 不能将枚举值放入容器;
    &Oslash; 可以在枚举类型中加入任意的字段和方法。
    新的枚举类型在语法上与C++的枚举非常相似:
    enum Season { winter, spring, summer, fall }
    下面是一个枚举的例子:
    public enum Coin {
    penny(1), nickel(5), dime(10), quarter(25);
    Coin(int value) { this.value = value; }
    private final int value;
    public int value() { return value; }
    }
    从这里可以看到,可以在枚举类型中声明其他的方法。不过,使用枚举类型中的方法是有一定技
    巧的。我们先看使用上述枚举类型的代码:
    public class CoinTest {
    public static void main(String[] args) {
    for (Coin c : Coin.VALUES)
    System.out.println(c + ": \t"
    + c.value() +"&cent; \t" + color(c));
    }
    private enum CoinColor { copper, nickel, silver }
    private static CoinColor color(Coin c) {
    switch(c) {
    case Coin.penny: return CoinColor.copper;
    case Coin.nickel: return CoinColor.nickel;
    case Coin.dime:
    case Coin.quarter: return CoinColor.silver;
    default: throw new AssertionError("Unknown coin: " + c);
    }
    }
    }
    尽管枚举类型成为了非原生类型,但仍然可以在switch 语句中使用枚举值进行判断。也可以在
    switch 语句中调用枚举类型中的方法,根据返回的值进行判断??这就是使用枚举类型中方法
    的技巧。另外请注意:Coin 和CoinColor 两个枚举类型都有一个枚举值名为nickel,但两者并
    不冲突,因为它们分属不同的名字空间。
    静态导入(static import)
    到目前为止,如果想要使用某个静态(static )成员值,那么你必须用“类名.成员名”的格式。
    例如,下列代码是用于取得π值的:
    double a = Math.PI;
    为了避免每次都必须引用类名,有人想出了一种名为“Constant Interface”的办法:将静态
    成员定义在一个接口中,让需要使用这些静态成员的类实现这个接口:
    // "Constant Interface" antipattern - do not use!
    public interface Physics {
    public static final double AVOGADROS_NUMBER = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS = 9.10938188e-31;
    }
    public class Guacamole implements Physics {
    public static void main(String[] args) {
    double moles = ...;
    double molecules = AVOGADROS_NUMBER * moles;
    ...
    }
    }
    这并不是一个好办法。“使用Physics 常数”是一个实现细节,是Guacamole 类自己的家务事。
    但在使用Constant Interface 之后,这些私事却通过接口暴露在众目睽睽之下,这是很糟糕的
    事情??如果Guacamole 类想放弃这些常数,改为使用另一个接口提供的常数,那么所有的
    client 代码都必须重新编译;另外,Physics 接口的改动也会导致重新编译。所以,Joshua Bloch
    将Constant Interface 归纳为一个反模式(anti-pattern),也就是说,你不应该这样做。
    有了静态导入的特性之后,就可以彻底将“使用常数”的细节从接口中剥离出来:
    import static org.iso.Physics.*;
    class Guacamole {
    public static void main(String[] args) {
    double molecules = AVOGADROS_NUMBER * moles;
    ...
    }
    }
    而上面那行获得π值的代码则可以改写为:
    import static java.lang.Math.*;
    ...
    double a = PI;
    元数据(metadata)
    在Java 的实际应用(尤其是J2EE)中,很多时候必须编写重复的样板文件(boilerplate)。
    例如,如果要定义一个JAX-RPC Web 服务,就必须同时提供接口类和实现类:
    public interface CoffeeOrderIF extends java.rmi.Remote {
    public Coffee [] getPriceList()
    throws java.rmi.RemoteException;
    public String orderCoffee(String name, int quantity)
    throws java.rmi.RemoteException;
    }
    public class CoffeeOrderImpl implements CoffeeOrderIF {
    public Coffee [] getPriceList() {
    ...
    }
    public String orderCoffee(String name, int quantity) {
    ...
    }
    }
    有了元数据工具之后,就不必再自己动手写这些麻烦并且与业务主题无关的东西了。你可以在源
    码中用特定的符号指定需要远程访问的方法,一个工具就会帮助你生成这些样板文件。使用元数
    据之后的代码大概是下面这样:
    import javax.xml.rpc.*;
    public class CoffeeOrder {
    @Remote public Coffee [] getPriceList() {
    ...
    }
    @Remote public String orderCoffee(String name, int quantity) {
    ...
    }
    }
    不过,到目前为止,这项特性还是主要针对Web 服务的。JSR 175 提供了一个框架,允许其他
    人定义元数据属性和处理工具。现在,唯一基于JSR 175 实现了元数据和处理工具定义的就是
    JSR 181,它定义的就是Web 服务元数据集。有一些Web 服务框架(例如Apache 的axis )
    已经可以非常轻易地完成Web 服务的自动部署。在axis 中,你只需编写一个普通的Java 源文
    件、将其放置在合适的路径下、并将其后缀名改为“.jws”,axis 就会自动将其部署为Web 服
    务。因此,在Java 中加上元数据特性,获益最大的肯定不是Web 服务开发者。
    实际上,另外两种颇受关注的编程方法学Aspect Oriented Programming(面向方面编程,
    AOP)和Design by Contract(按契约设计,DbC)或许可以从元数据工具中获得更多的帮助。
    另外,除了Web 服务之外,其他的J2EE 应用(例如EJB、JSP/Servlet)都需要大量的样板
    文件,例如部署描述符、远端代理等等。各大厂商的IDE(例如BEA Workshop 和IBM
    WebSphere Studio)中提供了向导来帮助生成这些样板,开源社群则多采用xDoclet 来处理
    样板文件。元数据工具可以为他们提供一个统一的标准。
    小结
    从根本上来说,J2SE 1.5的改进是为了更加方便开发者,使他们编程更加轻松、开发效率更高。
    目前,Tiger 项目仍在继续进行,J2SE 1.5还有可能加入其他的新特性,上述6 大新特性也可
    能做一些调整。
    Joshua Bloch 访谈原文请看:
    http://java.sun.com/features/2003/05/bloch_qa.html