无为

无为则可为,无为则至深!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

本文中,我们将讨论几个在 JDK1.5 中新的语言特征,包括:
  
  泛型( Generics -- 为集合( collections )提供编译时类型安全,无需每刻从 Collections 取得一个对象就进行强制转换( cast
  增强的 “for” 循环( Enhanced For loop -- 减少迭代器 (iterator) 的潜在错误( error-proneness
  自动置入 / 自动取出( Autoboxing/unboxing -- 无需在基本类型( primitive types )(例如 double )和包装类型( wrapper types )(例如 Double )之间人工地进行转换。
  类型安全的枚举( Typesafeenums -- 提供类型安全枚举模式的各项好处。
  静态导入( Static import -- 无需在使用其他类的静态成员变量前缀其类名 . 这将使得代码更为简洁。
  元数据( Metadata -- 使编程人员避免编写样板化代码( boiler plate code ),并提供机会进行宣告式程式设计 (declarative programming)
  让我们详细讨论每个新特性,并看一些例子。
  
  泛型( Generics
  泛型是 JDK1.5 中一个最 的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出 ClassCastExceptions 的可能。在 JDK1.5 中,你可以声明一个集合将接收 / 返回的对象的类型。在 JDK1.4 中,创建雇员名字的清单( List )需要一个集合对象,像下面的语句:
  
   List listOfEmployeeName = new ArrayList();
  
  在 JDK1.5 中,你将使用下面语句
  
   List<String> listOfEmployeeName = new ArrayList<String>();
  
  最 的是,如果你试图插入非 string 类型的值,你将在编译时发现并且修正这类问题。没有泛型,你会发现这样一个 bug ,当你的客户调用后会告诉你,你所编写的程序抛出 ClassCastException 异常而崩溃。
  
  另外,当你从集合中得到一个元素时你无需进行强制转换。故原先为:
  
   String employeeName = ((String) listOfEmployee.get(i));
  
  而下面的语句将比上面的更加简单:
  
   String employeeName = listOfEmployee.get(i);
  
  不清楚对象的类型而强制转换对象是不合理的,并且更重要的是,它将在运行时失败。假使用户无意间传入一个包含 string buffers 类型而非 string 类型的集合,那结果会怎样呢。在 Listing A 中,客户被要求传入一个编译器无法强制的 strings 类型集合。 Listing B 中显示了同样的方法使用泛型是如何实现的。
  
   Listing A
  
   staticbooleancheckName(Collection employeeNameList, String name) {
  
    for (Iteratori = employeeNamList.iterator(); i.hasNext(); ) {
  
   String s = (String) i.next();
  
   if(s.equals(name)){
  
    return true;
  
   //print employee name here ......
  
   }
  
   }
  
   return false;
  
   }
  
   Listing B
  
   staticbooleancheckName(Collection<String> employeeNameList, String name) {
  
   for (Iteratori = employeeNamList.iterator(); i.hasNext(); ) {
  
    if(i.next().equals(name)){
  
    return true;
  
    //print employee name here ......
  
    }
  
    }
  
   return false;
  
   }
  
  现在,通过方法签名可以清楚知道输入集合必须只能包含 strings 。如果客户试图传入一个包含 string buffers 的集合,程序将不会编译。同时注意,该方法不包含任何强制转换。它只需要短短一行,一旦你习惯泛型后,它也更加清晰。
  
  在 JDK 当前版本下的 For 循环语法如下:
  
   void printAll(Collection c) {
      for (Iteratori = c.iterator(); i.hasNext(); ) {
          Employee emp = (Employee)i.next();
          System.out.println(emp.getName());
      }
   }
  现在,用增强的 For 语句实现相同方法:
  
   voidprintAll(Collection c) {
      for (Object o : c)
          System.out.println((TimerTask)o).getName());
   }
  
  在这类 For 循环中,你应该将 ":" 看成 "in" ,所以,在该例中可以看成 "for Object o in c" 。你可以发现这种 For 循环更具可读性。
  
  自动置入 / 自动取出( Autoboxing/unboxing
   Java 有基本数据类型,在这些基本数据类型周围又有包装类。通常,编程人员需要将一种类型转换成另一种。看看 Listing C. 中的代码片断。
  
   Listing C
  
   public class Employee {
  
   private static final Integer CHILD = new Integer(0);
  
   public static void main(String args[]) {
  
   //code for adding n to an Integer
  
   int n=10;
  
   Integer age= new Integer(30);
  
   Integer ageAfterTenYear= new Integer(age.intValue +10);
  
   }
  
   }
  
  请注意,用于计算 ageAfterTenYear 的内循环代码看上去是多么杂乱。现在,在 Listing D. 中看看相同的程序使用 autoboxing 重写后的样子。
  
   Listing D
  
   public class Employee {
  
      public static void main(String args[]) {
  
       int n=10;
  
       Integer age= new Integer(30);
  
       Integer ageAfterTenYear= age +10;
  
      }
  
   }
  
  有一件事值得注意的:在先前,如果你取出( unbox Null 值,它将变为 0 。在次代码中,编译器将自动地转换 Integer int 然后加上 10 ,接着将其转换回 Integer.
  
  类型安全的枚举( Typesafeenums
  类型安全枚举提供下列特性:
  
  他们提供编译时类型安全。
  他们都是对象,因此你不需要将他们放入集合中。
  他们作为一种类的实现,因此你可以添加一些方法。
  他们为枚举类型提供了合适的命名空间。
  他们打印的值具有情报性( informative 如果你打印一个整数枚举( intenum ),你只是看见一个数字,它可能并不具有情报性。
  例一:
  
   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; }
   }
  
  静态导入( Static import
  静态导入使代码更易读。通常,你要使用定义在另一个类中的常量( constants ),像这样:
  
   import org.yyy.pkg.Increment;
  
   class Employee {
      public Double calculateSalary(Double salary{
          return salary + Increment.INCREMENT * salary;
      }
   }
  
  当时使用静态导入,我们无需为常量名前缀类名就能使用这些常量,像这样:
  
   import static org.yyy.pkg.Increment;
  
   class Employee {
      public Double calculateSalary(Double salary{
          return salary + INCREMENT * salary;
      }
   }
  
  注意,我们可以调用 INCREMENT 这一常量而不要使用类名 Increment.
  
  元数据( Metadata
  元数据特征志于使开发者们借助厂商提供的工具可以进行更简易的开发。看一看 Listing E. 中的代码。
  
   Listing E
  
   import org.yyy.hr;
  
   public interface EmployeeI extends Java.rmi.Remote {
  
      public String getName()
  
          throwsJava.rmi.RemoteException;
  
      public String getLocation ()
  
          throwsJava.rmi.RemoteException;
  
   }
  
   public class EmployeeImpl implements EmployeeI {
  
      public String getName(){
  
  
  
      }
  
      public String getLocation (){
  
  
  
      }
  
   }
  
  通过元数据的支持,你可以改写 Listing E 中的代码为:
  
   import org.yyy.hr;
  
   public class Employee {
      @Remote public String getName() {
          ...
      }
      @Remote public public String getLocation() {
          ...
      }
   }
  
  正像你所看到的,所有样板化的代码都不见了。
  
  这些新特性和规格说明将在 JDK1.5 中实现。它将提供 Java 编程社区更多的选择以编写鲁棒的、可扩展的代码。认真的 Java 编程人员将感到着手去熟悉这一 Java 编程语言的新版本是很有益的。



凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。

posted on 2006-06-11 17:28 草儿 阅读(207) 评论(1)  编辑  收藏 所属分类: java

Feedback

# re: JDK1.5中新的语言特征分类介绍 2006-07-31 16:30 neptunecai
你知道哪些1.4中的API在1.5中被deprecated了吗?
mars_21@sina.com。谢谢  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: