探索 Eclipse V3.1 的新特性

Eclipse 简介

经过一段相对较短时间,Eclipse 已经成为开发其他 IDE 和开发许多问题领域的不同应用程序的流行基石。

例如,Ruby 开发工具是一组特定于 Ruby 的插件,可以把 Eclipse 变成强大的 Ruby 编辑器。同时,Azureus 这个得到高度评价和广泛应用的 Java 应用程序,能够下载 BitTorrent 的 torrent (大型文件集合),它以 Eclipse 的富客户端平台(RCP)为基础。

当然,Eclipse 也是一种功能日益强大、日益受到人们欢迎的 IDE,可以编写许多编程语言的代码。由于它有着可扩展的框架,因此开发人员往往会单独为 Eclipse 调整最尖端的开发工具。因为它的流行,商业开发工具厂商(例如 Rational® 和 Oracle)现均已提供专门为与 Eclipse 集成而设计的产品。

另外,Eclipse 的管理主体 —— Eclipse 基金会 —— 不断为核心项目注入资金,以进一步扩展 Eclipse 的功能。例如,Eclipse 测试和性能工具平台(TPTP)项目就把测试、性能评测和监视工具添加到核心 Eclipse 平台。另一个项目,Eclipse Web 工具平台(WTP)项目,添加的工具和技术则有助于开发以 Web 为中心的应用程序。

总而言之,Eclipse 是大量工具的平台和保护伞,它促进了开发、便利了重新开发(或 重构)、简化了到多平台的移植(通过像 Standard Widget Toolkit(SWT)这样的软件包),并管理整个软件开发生命周期 —— 从第一行代码到生产系统的监视。

Eclipse V3.1

在 2005 年 6 月,历经了一整年的开发之后,Eclipse 基金会发布了一个有重大意义的 Eclipse 新版本:V3.1。新发行版中的改进涉及的范围从核心 Eclipse 平台到 Eclipse JDT 和 Eclipse 插件开发环境(PDE)(开发扩展 Eclipse 的软件的完整环境)。如果您使用 Eclipse 时间不长,或者根本没有用过,那么 V3.1 值得仔细研究。

Eclipse V3.1 中的新特性 —— 不论大小 —— 包括:

更好的性能
在 V3.1 问世之前,Eclipse 有着迟缓的名声。为了解决许多开发人员的顾虑,新版本开发过程中有相当多的时间和精力都花在了对平台的优化上,结果相当令人满意。在 V3.1 中,Eclipse 的内存占用更少,整个 Eclipse 平台速度更快,跨各种平台(包括 Mac OS X、Windows 和 Linux)的响应性更好。而且,平台处处都加上了工具,从而使性能的下降(或提高)更透明直观。

例如,图 1 中显示了一些 Eclipse V3.1.1、最新的维护发布版的评测结果。


图 1. Eclipse V3.1.1 的部分性能标准测试
Eclipse 3.1.1 的性能

类似的图表对于 Eclipse 的后续发行版也存在,甚至包括软件的 nightly builds 版。在 Eclipse 的 Web 站点上可以查看更多标准测试结果。

更智能化的帮助
Eclipse V3.1 包含上下文敏感的全新动态帮助系统,能够跟上用户从一个任务到另一个任务的变化脚步。从一个视图转到另一个视图 —— 甚至从一代码到另一行代码,动态帮助视图都会更新,为当前的任务提供最相关的主题和文档列表。
增强的可用性
大大小小的变化让 Eclipse 平台用起来更简单。例如,整个平台现在支持双向语言,可以使用关键字过滤首选项或属性 —— 不必在长长的列表中乱翻(图 2 显示了与关键字 tab 匹配的首选项),可以一次导入多个项目,甚至能从 tar 或 zip 档案导入,插件安装也简单到只要安装一个 jar 文件,然后新的安装向导就会自动安装插件的全部相关项。

图 2. 搜索所有与 tab 有关的首选项面板






J2SE V1.5

除了以上列出的许多好处之外,所有在 J2SE V1.5 中能发现的新的 Java 语言增强在 Eclipse V3.1 中都支持,包括泛型、自动装箱、增强的 for 循环、注释、枚举类型(enums)以及其他。J2SE V1.5 不仅扩展了 Java 语言,而且它的许多特性还让编程语言更具类型安全性,使得编译时错误和运行时错误更少。

例如,清单 1 演示了一些 J2SE V1.5 的新特性:


清单 1. J2SE V1.5 的新特性

package demo;

import java.util.ArrayList;

public class Shapes {

public enum Shape {
SQUARE (2),
CIRCLE (1),
TRIANGLE (3);

private final Integer data;

Shape(int i) {
this.data = i;
}

public int value() {
return this.data;
}
}

public static void main(String[] args) {
ArrayList<Shape> a = new ArrayList<Shape>();
for (Shape s: Shape.values()) {
a.add(s);
}

for (int i = 0; i < a.size(); i++) {
Shape s = a.get(i);
double perimeter = 0;

switch (s) {
case SQUARE:
perimeter = s.value() * 4;
break;
case CIRCLE:
perimeter = s.value() * 3.14159;
break;
case TRIANGLE:
perimeter = s.value() * 3;
break;
}

System.out.print("The perimeter of a " +
s.value() + "-inch + s + " is " +
perimeter + " inches" );
}
}
}

很快,J2SE V1.5 的新枚举类型 成为全功能的类,能够拥有方法、属性和其他。自动装箱自动拆箱 使原语类型可快速提升为兼容类并支持相反的功能。所以,this.data = i 不要求升级(会在 this.data = new Integer(i) 这样的代码中看到)。

通用集合(例如 ArrayList)现在可以接受类型参数(例如 Shape),把集合的成员限制在指定类型内。而且,集合返回的类型也是受限的。这样,像 a.get(i) 这样的语句不再一定要“降级”或从 Object 类型转换到 Shape。后一套特性合起来叫作 泛型

最后,(Shape s: Shape.values()) 这段代码是列表成员迭代的一个新的快捷方式。

这一节提供了 Eclipse V3.1 中的众多改进的一个简短列表(为了简洁)。上面列出的许多改进以及其他一些改进,都将在本教程中演示。

泛型编程

J2SE V1.5 为 Java 新增的一个最有价值的特性就是泛型。为了体会泛型的价值和目的,请看清单 2。


清单 2. 从哈希表插入和提取元素


import java.util.Hashtable;
class Demo
{
public static void main(String[] args)
{
Hashtable h = new Hashtable();

h.put(new Integer(0), "Horse Feathers");
String s = (String) h.get(new Integer(0));
System.out.println(s);
}
}

像这样的代码如果反复编写会很费力(肯定可以证明),而且突出显示的代码行的复杂性则掩饰了它实际上的简单目的。更糟的是,编译器捕捉不到不匹配的类型——例如用 h.get() 检索出对象之后如果转换到错误的类型。实际上,向下转型(downcasting)(沿着对象继承树向下转型的过程,比如从 ObjectString)是 Java 程序的运行时 bug 的一大源头。

当然,还可以用固定类型实现自己的哈希表。例如,MyStringHashTable 可能包装了通用的 Hashtable,而且只通过 Integer 索引添加了 String 元素。在这种情况下,MyStringHashTable.put()MyStringHashTable.get() 应当适当地重新做定义,只接受类型正确的参数,并返回 String

虽然这样的 MyStringHashTable 是类型安全的,但它就不再灵活了。要把新形式的数据保存到哈希表中,就必须在全新的独立对象中重新创建大多数 MyStringHashTable 代码。

进入泛型

理想情况下,像 Hashtable 类这样的东西,应当既灵活 严格(类型安全):例如,键和值的类型应当是在初始化的时候参数化,避免类型转换的需要,允许编译器捕获类型不匹配。而且,实际上,参数化类型也是 Java V1.5 的新泛型的基础。






创建和使用泛型

在这一节,使用 Eclipse 及其对泛型的支持创建和优化示例应用程序。

  1. 如果还没启动 Eclipse,请启动它,进入工作台创建新项目。要创建新项目,请选择 File > New > Project...。指定 Generics Example 作为项目名称,并从 JDI Compliance 区中选择 5.0(单击下拉菜单可以找到)。最后,单击 Finish
  2. 在新项目中创建 Java 类。请选择 File > New > Class,输入 demo 作为包名称,输入 Demo 作为类名。选中复选框,生成 public static void main(String[] args) 方法框架。现在,单击 Finish
  3. 在 Package Explorer 面板中单击新的 Demo 类,然后把清单 3 的代码复制并粘贴到 Demo.java 面板中。
    清单 3. 简单的泛型类


    package demo;

    class GenericContainer <A>
    {
    private A data;

    public GenericContainer(A data)
    {
    this.data = data;
    }

    public A get()
    {
    return data;
    }
    }

    public class Demo
    {
    public String storeString(String s)
    {
    GenericContainer<String> gc =
    new GenericContainer<String>(s);
    String t = gc.get();
    return t;
    }

    public Integer storeInteger(Integer i)
    {
    GenericContainer <Integer> gc =
    new GenericContainer<Integer> (new Integer(i));
    return gc.get();
    }

    public static void main(String[] args) {
    Demo d = new Demo();

    System.out.println(d.storeString("This is a test"));
    System.out.println(d.storeInteger(18000));
    }
    }

  4. Ctrl+S 组合键保存代码,并选择 Run > Run...。出现 Run 对话框时,单击右下角的 Run 按钮。输出面板中应产生以下输出:

    This is a test
    18000

  5. 将鼠标指针悬停在 gc.get() 每个调用上。若您悬停在 storeString 中的第一次使用上,会弹出一个小提示信息,指示 gc.get() 返回一个 String,而悬停在第二个使用时,会提示实例方法返回了一个 Integer (请参阅图 3)。

图 3. 跟踪一个通用方法调用,查看它返回的类型
鼠标悬停在通用方法调用上

现在您知道了为什么要把泛型添加到 Java 中,以及泛型的工作方式。下面将介绍 Eclipse V3.1 是如何支持和增强泛型的。






用泛型捕获错误

因为泛型的目的是帮助避免向下转型错误,所以 Eclipse 会标记出可通过泛型的使用获益的操作。

例如,请在 Eclipse 中用 5.0 编译器设置创建下面这个简短的 Java 应用程序:


package demo;

import java.util.ArrayList;

public class Demo2 {

public static void main(String[] args) {
ArrayList a = new ArrayList();
a.add(new Integer(1));
}
}

代码输入之后,两个小图标 —— 一个蓝色灯泡和一个警告标记 —— 会出现在 a.add(...) 的起始行上,如图 4 所示。如果将鼠标悬停在这个图标上,会出现一条消息,提示您 ArrayList 应当参数化。


图 4. Eclipse 指出更适于使用泛型的时机
标记出泛型的适合之处

类型安全更强的代码是 ArrayList>Integer< a = new ArrayList>Integer<()

Eclipse 还提供了重构技术,可以促进泛型的使用。请看清单 4.


清单 4. 将代码重构为使用泛型


package demo;

import java.util.ArrayList;
import java.util.List;

public class Demo3 {
public class Brother {
private String name;

public Brother(String s) {
name = s;
}

public String get() {
return name;
}
}

public static void main(String[] args) {
Demo3 d = new Demo3();

List l = new ArrayList(3);
l.add(d.new Brother("Groucho"));
l.add(d.new Brother("Harpo"));
l.add(d.new Brother("Chico"));
l.add((Brother) l.get(1));

for (int i = 0; i < l.size(); i++) {
Brother b = (Brother) l.get(i);
System.out.println(b.get());
}
}
}

输入以上代码后,Eclipse 将使用蓝色灯泡和黄色波浪线标记许多行,表示可以做改进。要将其重构为使用泛型,请选择 Refactor > Infer Generic Type Arguments。出现下一对话框时,把两个选项都选中,然后单击 Preview 按钮。Eclipse 会展示要做的变化,如图 5 所示。


图 5. 在 Eclipse 中预览重构为使用泛型的情况
标记出适于使用泛型的位置

Eclipse 重构器不仅对 ListArrayList 进行参数化,而且删除了 for 循环中的类型转换。单击 OK 接受修改。代码转换为:


List>Brother< l = new ArrayList>Brother<(3);
...
l.add(l.get(1));

最后,在任何 Eclipse 处理非泛型类型的地方,都能处理泛型类型。例如,可以安全地把泛型类型改名。






新循环

随着泛型的加入,Java V5 现在支持 foreach 的一种快捷方式,对列表中的元素进行迭代。输出 List l 成员的旧式 for 循环可改写为一种更干净的格式:


for (Brother b: l)
System.out.println(b.get());

就像对许多旧 Java 语言特性一样,Eclipse V3.1 包含了一个针对 J2SE V1.5 的新 foreach 构造的模板。Eclipse 不仅会生成 foreach 代码,还会猜测(根据上下文和位置)要对哪个集合进行迭代。

例如,在最后一个 l.add() 后输入 fore,然后按下 Ctrl+Space。Eclipse 会把 foreach 模板作为选项提供,并显示它要生成的代码,如图 6 的示。


图 6. Eclipse 能够根据上下文自动生成 foreach 循环
使用 foreach 模板

选择推荐的 foreach 模板,生成这个代码:


for (Brother brother : l) {

}

J2SE V1.5 语言的更多特性

泛型的添加必将减少 Java 代码中的 bug 数量,而其他 J2SE V1.5 特性无疑能够提高您的生产力。

J2SE V1.5 引入了许多可以简化开发的语言特性。本教程将介绍其中的两个:自动装箱和枚举类型。

自动装箱

自动装箱和自动拆箱提供了简单、干净的语法,用来把原语值分配给对象,以及从对象读取原语值。例如,在过去,要这样写:


public class Box {
public Box(Integer i) {
...
}
}

...

Box o = new Box(new Integer(1));

而现在可以这样写:Box n = new Box(2)。更好的是, Eclipse V3.1 能够突出显示自动装箱和自动拆箱的实例。

要查看这个特性,请将清单 5 复制并粘贴到 Eclipse 中的新类内。


清单 5. 自动装箱和自动拆箱演示


package demo;

public class Box {

private Integer data;

public Box(Integer i) {
data = i;
}

public Integer get() {
return data;
}

public static void main(String[] args) {
Box o = new Box(new Integer(100));
Box n = new Box(200);
int oi = o.get().intValue();
int ni = n.get();
System.out.println("Your numbers are " + oi
+ " and " + ni);
}
}

请选择 Windows > Preferences...,再选择 JAVA> Editor > Syntax Coloring > JAVA> Auto(un)boxed Expressions,显示图 7 所示的选项。选择 Enable,然后选择 Bold,然后单击 ApplyOK


图 7. 突出显示的装箱和拆箱实例
突出显示的装箱和拆箱实例

在返回 Eclipse 中的类面板时,装箱的实例 new Box(200) 和拆箱的实例 ni = n.get(),分别按照规范用红色和粗体标记:


图 8. 突出显示的装箱和拆箱实例
突出显示的装箱和拆箱实例

如果想让编译器额外为自动装入和自动拆箱的实例加标记,可选择 Window > Preferences,然后选 JAVA> Compiler > Errors/Warnings > J2SE 5.0 Options,再将 Boxing and unboxing conversions 设置成 WarningError 即可。

请记住,可以在 Preference 对话框的搜索框中输入关键字,从而迅速地找到任何首选项。例如,选择 Window > Preferences,然后在搜索框中输入 boxing。带有相关选项的面板就会出现,如图 9 所示。


图 9. 找到影响自动装箱和自动拆箱的首选项
找到影响自动装箱和自动拆箱的首选项





枚举类型

在 Java 语言的这一发行版出现之前,枚举通常是用手工实现的:


public static final int GROUCHO_MARX = 0;
public static final int HARPO_MARX = 1;
public static final int CHICO_MARX = 2;
public static final int KARL_MARX = 3;

确实非常老套,而且这类人为的枚举类型不是类型安全的,缺少名称空间,是非常 脆弱的,也就是说,修改常量就会带来巨大的破坏,因为值被编译到一个或多个模块或程序中。如果没有重新编译或重新安装引用这些常量的每个模块,那么系统的行为就无法预测。

为了修正自写枚举的许多问题,J2SE V1.5 添加了一个全功能的类,名为 enum 类型,用来代表枚举类型。

从最简单的形式上看,J2SE V1.5 的枚举类型与其他编程语言中的类似构造很相似。例如,用现代 Java 语言编写的功能相同的代码如下:


public enum Actors {
GROUCHO, CHICO, HARPO, KARL
}

以下代码将遍历所有值的列表:


package demo;

public class Demo4 {
public enum Actors {
GROUCHO, CHICO, HARPO, KARL
}

public static void main(String[] args) {
for (Actors actor : Actors.values())
System.out.println("Say hello to " + actor);
}
}

因为枚举现在是 Java 语言中的类,所以 Eclipse 提供了独立的对话框来创建它们。请选择 File > New > Enum 打开图 10 所示的对话框。


图 10. 用 Eclipse 创建新的 Java 枚举
Java 枚举

Java 枚举也可以比较和序列化。甚至,枚举还能有方法和属性,就像其他对象一样。所以,前面的 Actors 可以进一步扩展成这样:


package demo;

public class Demo4 {
public enum Actors {
GROUCHO ("What about this sanity clause?"),
CHICO ("Everyone knows there ain't no such " +
"thing as sanity clause!"),
KARL ("Ugh!"),
HARPO ("Honk! Honk!");

private final String line;

Actors(String s) {
this.line = s;
}

public String line() {return line;}
}

public static void main(String[] args) {
for (Actors actor : Actors.values())
System.out.println(actor.line());
}
}

如果把这段代码复制粘贴到新的 Eclipse 类 Demo4 中,并运行代码,即可看到:


What about this sanity clause?
Everyone knows there ain't no such thing as sanity clause!
Ugh!
Honk! Honk!


若 Outline 视图处于打开状态,Eclipse 会提供新枚举的概要视图,如图 11 所示。


图 11. 新的 Java 枚举类型类的概要
枚举概要

其他出色的特性

除了提高编程的速度和准确性之外,Eclipse V3.1 还添加了许多特性,当您在 Eclipse 界面中导航时,可为您提供协助。上文中已提及的有:可以搜索许多 Eclipse 首选项面板,根据关键字找到属性;在编辑器中可以突出显示多种语言构造,让代码更具可读性。

还有一些便利之处可能会给您带来一些帮助。

快捷键

在任何 Eclipse 编辑器或视图中,按 Ctrl+Shift+L 即可看到可用的快捷键(key binding)的完整列表。例如,在 Java 编辑器中,按 Ctrl+Shift+L 会显示出一个长长的特性列表,可以直接通过键盘使用(请参阅图 12)。


图 12. 按下 Ctrl+Shift+L 显示所有快捷键
所有快捷键的列表

General > Keys 首选项页面中也可以找到快捷键的列表。(也在以在快捷键列表中用 Ctrl+Shift+L 直接打开这个页面,如图 12 底部的提示所示。)






动态帮助

因为 Eclipse 如此流畅地整合了这么多工具,所以只要轻点鼠标,即可方便地从一个编辑器切换到分析器或项目编辑器。Eclipse V3.1 中的帮助系统已改进,可以跟得上您工作的脚步。

如果按下 F1 或从菜单中选择 Help > Dynamic Help,那么 Eclipse 会显示上下文敏感的帮助面板,随着在任务之间的切换,帮助内容也会发生动态变化。帮助视图如图 12 所示。


图 13. Eclipse 的动态帮助系统
Eclipse 的动态帮助系统

打开一个 Java 文件或本教程中的示例,并单击不同的行。您可以看到帮助视图会根据上下文发生变化。在进行以下几节的学习时,请保持帮助视图打开。






注释

J2SE V1.5 的注释允许把 Java 类类型和方法的元数据附加到源代码。然后注释就可以影响编译过程(甚至可以在运行时查询注释)。

如果没有打开自动装箱和自动拆箱的编译器报警,现在请打开,而且如果必要,请重新打开自动装箱的示例代码。报警打开后,自动装箱和自动拆箱的实例就会被加上标记。

点击第一个警报图标。应当得到两个选项:一个是把常量 200 释放到本地变量,另一个是添加 @SuppressWarnings 'boxing' 注释到 main()。请选择后者。代码变成这样:


@SuppressWarnings("boxing")
public static void main(String[] args) {
...
}

现在,如果重新构建自动装箱示例,Eclipse 不会生成任何警告,而且前面显示的报警图标也被消除。

像其他语言构造一样,Eclipse V3.1 能够自动扩展可用的注释。例如,在自动装箱示例中,把光标放在 get() 方法旁,并输入 @D,然后按下 Ctrl+Space。在选项列表中,选择注释 @Deprecated,它表示这个方法已经作废了(也就是说,编写了更好的 get() 方法或者不再支持这个 get() 方法)。

根据首选项,get() 方法的名称在它定义的地方和调用这个方法的两行代码中将被废除(请参阅图 14)。


图 14. 注释方法,表明不再使用该方法
标注方法,表明它的使用已经作废

如果帮助视图仍然打开,请单击 @Deprecated 注释,最顶级入口会指向 java.lang.Deprecated 的 Javadoc。


结束语

不论是开发工具、应用程序或者大量的 Java 代码,Eclipse V3.1 都能提高您的生产力。它运行在所有最流行的操作系统上 —— 而且运行速度更快 —— 而且仍然在不断增加巨大的特性集。

实际上,如果您是 Java 开发人员,那么 Eclipse 的 Java 开发工具和它的测试和性能工具平台为创建、调试、优化和监视应用程序提供了丰富的工具套件。Java 2 标准版 V1.5 让 Java 的类型安全更高、更易使用,而 Eclipse V3.1 则支持和强化了 J2SE V1.5 的所有关键构造。

正如从本文演示的几个示例中可以看到的,在 Eclipse 中编写 Java 程序是一件充满乐趣的工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值