JDK 1.6 新特性

Desktop类和SystemTray类

JDK 1.6 AWT 新增加了两个类:Desktop 和 SystemTray

前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如,用记事本打开以txt为后缀名的文件),用系统默认的打印机打印文档;后者可以用来在系统托盘区创建一个托盘程序。

这两个类都为工厂类,其构造函数是private,这也就意味着我们需要调用其静态方法来获取此类的实例。

Desktop类

Desktop 类允许 Java 应用程序启动已在本机桌面上注册的关联应用程序,以处理 URI 或文件。
支持的操作包括:

  • 启动用户默认浏览器来显示指定的 URI;
  • 启动带有可选 mailto URI 的用户默认邮件客户端;
  • 启动已注册的应用程序,以打开、编辑或打印指定的文件。
  • 此类提供与这些操作对应的方法。这些方法查找在当前平台上注册的关联应用程序,并启动该应用程序来处理 URI 或文件。如果没有关联应用程序或关联应用程序无法启动,则抛出异常。
  • 应用程序被注册为 URI 或文件类型;例如,”sxi” 文件扩展名通常注册为 StarOffice。注册、访问和启动关联应用程序的机制与平台有关。

每个操作都是由 Desktop.Action 类表示的一种动作类型。
注:当调用一些动作和执行关联应用程序时,将在与启动 Java 应用程序相同的系统上执行它们。

与Desktop类具有类似功能的类有Runtime类。

SystemTray类

  SystemTray 类表示桌面的系统托盘。在 Microsoft Windows 上,它被称为“任务栏状态区域 (Taskbar Status Area)”,在 Gnome 上,它被称为“通知区域 (Notification Area)”,在 KDE 上,它被成为“系统托盘 (System Tray)”。系统托盘由运行在桌面上的所有应用程序共享。

  在某些平台上,可能不存在或不支持系统托盘,在这种情况下,getSystemTray() 将抛出 UnsupportedOperationException。要检查系统托盘是否受支持,可以使用 isSupported()。

  SystemTray 可以包含一个或多个 TrayIcon,可以使用 add(java.awt.TrayIcon) 方法将它们添加到托盘,当不再需要托盘时,使用 remove(java.awt.TrayIcon) 移除它。TrayIcon 由图像、弹出菜单和一组相关侦听器组成。

  每个 Java 应用程序都有一个 SystemTray 实例,在应用程序运行时,它允许应用程序与桌面系统托盘建立连接。SystemTray 实例可以通过 getSystemTray() 方法获得。应用程序不能创建自己的 SystemTray 实例。

示例:

TrayIcon trayIcon = null;
if (SystemTray.isSupported()){
    // get the SystemTray instance
    SystemTray tray = SystemTray.getSystemTray();
    // load an image
    Image image = Toolkit.getDefaultToolkit.getImage(...);
    // create a action listener to listen for default action executed on the tray icon
    ActionListener listener = new ActionListener(){
        public void actionPerformed(ActionEvent e)              {
            // execute default action of the application
            // ...
        }
    };
    // create a popup menu
    PopupMenu popup = new PopupMenu();
    // create menu item for the default action
    MenuItem defaultItem = new MenuItem(...);
    defaultItem.addActionListener(listener);
    popup.add(defaultItem);
    /// ... add other items
    // construct a TrayIcon
    trayIcon = new TrayIcon(image, "Tray Demo", popup);
    // set the TrayIcon properties
    trayIcon.addActionListener(listener);
    // ...
    // add the tray image
    try{
        tray.add(trayIcon);
    }
    catch (AWTException e){
        System.err.println(e);
    }
    // ...
}
else{
    // disable tray option in your application or
    // perform other actions
    ...
}
// ...
// some time later
// the application state has changed - update the image
if (trayIcon != null){
    trayIcon.setImage(updatedImage);
}
// ...

使用JAXB2来实现对象与XML之间的映射

JAXB(Java Architecture for XML Binding)可以将一个 Java 对象转变成为 XML 格式,反之亦然。

我们把对象与关系型数据库之间的映射称为ORM,其实也可以把对象与XML之间的映射称为OXM(Object XML Mapping)。

JAXB 是 Java EE 的一部分,在JDK1.6中,SUN将其放到了 Java SE 中,这也是SUN的一贯做法。JDK1.6中自带的这个 JAXB 版本是2.0,比起1.0(JSR 31)来,JAXB2(JSR 222) 用 JDK5 的新特性注解【Annotation】来标识要作绑定的类和属性等,这就极大简化了开发的工作量。

实际上,在 Java EE 5.0中,EJB 和 Web Services 也通过Annotation来简化开发工作。另外,JAXB2在底层是用StAX(JSR 173)来处理XML文档。除了 JAXB 之外,我们还可以通过 XMLBeans 和 Castor 等来实现同样的功能。

STAX

STAX(JSR 173) 是 JDK1.6 中除了 DOM 和 SAX 之外的又一种处理XML文档的API。

STAX的来历 – 在 JAXP1.3(JSR 206)有两种处理XML文档的方法:DOM(Document Object Model)SAX(Simple API for XML)

由于 JDK1.6 中的 JAXB2(JSR 222) 和 JAX-WS 2.0(JSR 224) 都会用到 StAX 所以 Sun 决定把 StAX 加入到 JAXP 家族当中来,并将 JAXP 的版本升级到 1.4(JAXP1.4是JAXP1.3的维护版本)。JDK1.6 里面 JAXP 的版本就是 1.4。

  • StAX(The Streaming API for XML) 是一种利用拉模式解析(pull-parsing)XML文档的API。StAX 通过提供一种基于事件迭代器(Iterator)的API让程序员去控制xml文档解析过程,程序遍历这个事件迭代器去处理每一个解析事件,解析事件可以看做是程序拉出来的,也就是程序促使解析器产生一个解析事件然后处理该事件,之后又促使解析器产生下一个解析事件,如此循环直到碰到文档结束符;
  • SAX 也是基于事件处理xml文档,但却是用推模式解析,解析器解析完整个xml文档后,才产生解析事件,然后推给程序去处理这些事件;
  • DOM 采用的方式是将整个xml文档映射到一颗内存树,这样就可以很容易地得到父节点和子结点以及兄弟节点的数据,但如果文档很大,将会严重影响性能。

Compiler API

现在我们可以用 JDK1.6 的Compiler API(JSR 199)去动态编译 Java 源文件,Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。

  • javax.tools : Provides interfaces for tools which can be invoked from a program, for example, compilers.

这个特性对于某些需要用到动态编译的应用程序相当有用,比如 JSP Web Server,当我们手动修改JSP后,是不希望需要重启 Web Server 才可以看到效果的,这时候我们就可以用 Compiler API来实现动态编译JSP文件,当然,现在的 JSP Web Server 也是支持 JSP 热部署的,现在的 JSP Web Server 通过在运行期间通过Runtime.exec或ProcessBuilder来调用javac来编译代码,这种方式需要我们产生另一个进程去做编译工作,不够优雅而且容易使代码依赖与特定的操作系统;

Compiler API通过一套易用的标准的API提供了更加丰富的方式去做动态编译,而且是跨平台的。

轻量级Http Server API

JDK1.6 提供了一个简单的 Http Server API,据此我们可以构建自己的嵌入式Http Server,它支持Http和Https协议,提供了HTTP1.1的部分实现,没有被实现的那部分可以通过扩展已有的Http Server API来实现,程序员必须自己实现HttpHandler接口,HttpServer会调用HttpHandler实现类的回调方法来处理客户端请求,在这里,我们把一个Http请求和它的响应称为一个交换,包装成HttpExchange类,HttpServer负责将HttpExchange传给HttpHandler实现类的回调方法。

插入式注解处理API

插入式注解处理API(Pluggable Annotation Processing API) - (JSR 269):提供一套标准API来处理Annotations(JSR 175)

实际上 JSR 269 不仅仅用来处理Annotation,我觉得更强大的功能是它建立了 Java 语言本身的一个模型,它把method,package,constructor,type,variable,enum,annotation等Java语言元素映射为TypesElements(两者有什么区别?),从而将Java语言的语义映射成为对象,我们可以在javax.lang.model包下面可以看到这些类。所以我们可以利用 JSR 269 提供的API来构建一个功能丰富的元编程(meta programming)环境。

JSR 269 用 Annotation Processor 在编译期间而不是运行期间处理注解【Annotation】,Annotation Processor相当于编译器的一个插件,所以称为插入式注解处理。如果Annotation Processor处理Annotation时(执行process方法)产生了新的Java代码,编译器会再调用一次Annotation Processor,如果第二次处理还有新代码产生,就会接着调用Annotation Processor,直到没有新代码产生为止。每执行一次process()方法被称为一个round,这样整个Annotation processing过程可以看作是一个round的序列。

JSR 269 主要被设计成为针对 Tools 或者容器的API。举个例子,我们想建立一套基于注解的单元测试框架(如TestNG),在测试类里面用注解来标识测试期间需要执行的测试方法。

Console 类

JDK1.6 中提供了 java.io.Console 类专用来访问基于字符的控制台设备。你的程序如果要与 Windows 下的 cmd 或者 Linux 下的 Terminal 交互,就可以用Console类代劳。但我们不总是能得到可用的 Console,一个JVM是否有可用的Console依赖于底层平台和JVM如何被调用。如果JVM是在交互式命令行(比如Windows的cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的Console实例。

对脚本语言的支持

JDK1.6 增加了对脚本语言的支持(JSR 223),原理上是将脚本语言编译成 bytecode,这样脚本语言也能享用 Java 平台的诸多优势包括可移植性、安全等,另外由于现在是编译成 bytecode 后再执行,所以比原来边解释边执行效率要高很多。加入对脚本语言的支持后,对Java语言也提供了以下好处:

  1. 许多脚本语言都有动态特性,比如,你不需要用一个变量之前先声明它,你可以用一个变量存放完全不同类型的对象,你不需要做强制类型转换,因为转换都是自动的。现在Java语言也可以通过对脚本语言的支持间接获得这种灵活性。
  2. 可以用脚本语言快速开发产品原型,因为现在可以Edit-Run,而无需Edit-Compile-Run,当然,因为Java有非常好的IDE支持,我 们完全可以在IDE里面编辑源文件,然后点击运行(隐含编译),以此达到快速开发原型的目的,所以这点好处基本上可以忽略。
  3. 通过引入脚本语言可以轻松实现Java应用程序的扩展和自定义,我们可以把原来分布在在Java应用程序中的配置逻辑,数学表达式和业务规则提取出来,转用JavaScript来处理。

详细可参考:

Common Annotations

Common annotations 原本是 JavaEE 5.0(JSR 244)规范的一部分,现在SUN把它的一部分放到了 JavaSE 6.0中。

随着Annotation元数据功能(JSR 175)加入到Java SE 5.0里面,很多Java 技术(比如EJB,Web Services)都会用Annotation部分代替XML文件来配置运行参数(或者说是支持声明式编程,如EJB的声明式事务),如果这些技术为通用目的都单独定义了自己的Annotations,显然有点重复建设,所以,为其他相关的Java技术定义一套公共的Annotation是有价值的,可以避免重复建设的同时,也保证 Java SE 和 Java EE 各种技术的一致性。

Java DB

Java安装目录下除了 bin、jre 等目录,JDK 6 新增了一个名为 db 的目录。这便是 Java 6 的新成员:Java DB。这是一个纯 Java 实现、开源的数据库管理系统(DBMS),源于 Apache 软件基金会(ASF)名下的项目 Derby。它只有 2MB 大小,对比动辄上 G 的数据库来说可谓袖珍。但这并不妨碍 Derby 功能齐备,支持几乎大部分的数据库应用所需要的特性。

Java 程序员不再需要耗费大量精力安装和配置数据库,就能进行安全、易用、标准、并且免费的数据库编程。在这一章中,我们将初窥 Java DB 的世界,来探究如何使用它编写出功能丰富的程序。

JDBC 4.0

自动加载驱动

在 JDBC 4.0 之前,编写 JDBC 程序都需要加上以下代码:

Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();

Java.sql.DriverManager 的内部实现机制决定了这样代码的出现。只有先通过 Class.forName 找到特定驱动的 class 文件,DriverManager.getConnection方法才能顺利地获得 Java 应用和数据库的连接。这样的代码为编写程序增加了不必要的负担,JDK 的开发者也意识到了这一点。

从 Java 6 开始,应用程序不再需要显式地加载驱动程序了,DriverManager 开始能够自动地承担这项任务。

DriverManager 为什么能够做到自动加载呢?这就要归功于一种被称为 Service Provider 的新机制。

熟悉 Java 安全编程的程序员可能对其已经是司空见惯,而它现在又出现在 JDBC 模块中。JDBC 4.0 的规范规定,所有 JDBC 4.0 的驱动 jar文件必须包含一个 java.sql.Driver,它位于 jar 文件的 META-INF/services
目录下。这个文件里每一行便描述了一个对应的驱动类。其实,编写这个文件的方式和编写一个只有关键字(key)而没有值(value)的 properties 文件类似。同样地,‘#’之后的文字被认为是注释。有了这样的描述,DriverManager 就可以从当前在 CLASSPATH 中的驱动文件中找到,它应该去加载哪些类。

而如果我们在 CLASSPATH 里没有任何 JDBC 4.0 的驱动文件的情况下,调用代码会输出一个 sun.jdbc.odbc.JdbcOdbcDriver 类型的对象。而仔细浏览 JDK 6 的目录,这个类型正是在 %JAVA_HOME%/jre/lib/resources.jar 的 META-INF/services 目录下的 java.sql.Driver
文件中描述的。也就是说,这是 JDK 中默认的驱动。而如果开发人员想使得自己的驱动也能够被 DriverManager 找到,只需要将对应的 jar 文件加入到 CLASSPATH 中就可以了。

当然,对于那些 JDBC 4.0 之前的驱动文件,我们还是只能显式地去加载了

// 罗列本地机器上的 JDBC 驱动
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
    System.out.println(drivers.nextElement());
}

其它

详细列表可参考:《Java 注解》博文 -> Common Annotations

赞赏

猜你喜欢

转载自blog.csdn.net/fanxiaobin577328725/article/details/81977502