【J2SE归档总结】0x10 JDK1.5新特性

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)。

Ex:

===============================================================================================================================

1、泛型(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的集合,程序将不会编译。同时注意,该方法不包含任何强制转换。它只需要短短一行,一旦你习惯泛型后,它也更加清晰。

================================================================================================================================

2、在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循环更具可读性。

================================================================================================================================

3、自动置入/自动取出(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.。

Integer 自动装箱

【享元模式】 flyweight

Ex: 有很多个小的对象,他们有很多个属性相同,把他们变为一个对象,那些不同的属性,变为方法的参数,称之为外部状态那些相同的属性称之为方法的内部状态

1.       word中输入英文字母  26个英文字母  并不创建每个对象(字母全部给缓存起来)

2.       windows中的图标  只需要指明引用位置

3.       在值-128~127之间  (经常使用,不改变数据)就不用new Integer(127)

package com.j2se.demo.basic;

public class AutoBox {
	
//	享元模式:有很多小的对象,他们有很多相同的属性,把他们变为一个对象,那些不同的属性变为方法的参数,称之为对象的外部状态,那些相同的属性
//	称之为方法的内部状态
//	Ex:
//	1.Windows文件图标库
//	2.Word文档的文件图标
//	Integer自动装箱	 范围是-127~128(认为这段范围内的额数据比较常用)
	public static void main(String[] args) {
		// (true)
		Integer i1 = 12;
		Integer i2 = 12;
		System.out.println(i1 == i2);

		// (false)
		Integer i3 = -129;
		Integer i4 = -129;
		System.out.println(i3 == i4);

		// (true)
		Integer i5 = 127;
		Integer i6 = 127;
		System.out.println(i5 == i6);
	}
}



================================================================================================================================

4、类型安全的枚举(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; 
          }
  }

枚举:(类,构造函数,方法,字段)

一些方法在运行时,他需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。

public class Grade {
	private Grade() {
	}

	public static final Grade A = new Grade();
	public static final Grade B = new Grade();
	public static final Grade C = new Grade();
	public static final Grade D = new Grade();
	public static final Grade E = new Grade();
	public static final Grade F = new Grade();
}
等同于 如下代码:
//枚举  相当于定义了一个类
	enum Grade2{
		A,B,C,D,E,F;
	}

枚举类具有如下特性:

1.    枚举类也是一种特殊形式的Java

2.    枚举类中声明的每一个枚举值都代表枚举类的一个实例对象

3.    Java类的普通类一样,在声明枚举类时,也可以声明属性,方法和构造函数,但枚举类的构造函数必须为私有的

4.    枚举类也可以实现接口,或者继承抽象类

5.    JDK5中扩展switch语句,他除了可以接受int byte char short外还可以接受一个枚举类型

6.    若枚举只有一个枚举值,则可以当作单态设计模式使用

================================================================================================================================

5、静态导入(Static import)

Import语句可以导入一个类或者某个包中的所有类

Import static 语句导入一个类中的某个静态方法或者所有静态方


  静态导入使代码更易读。通常,你要使用定义在另一个类中的常量(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.。
================================================================================================================================

6、元数据(Metadata)
  元数据特征志于使开发者们借助厂商提供的工具可以进行更简易的开发。看一看Listing E.中的代码。
  Listing E

  importorg.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中的代码为:
  importorg.yyy.hr;

  public class Employee {
  @Remote 
    public String getName() {
  ...
  }
  @Remote 
    public public String getLocation() {
  ...
      }
  } 

可变参数:

参数类型相同的情况下;不必构建多个重载函数使用可变参数

package com.j2se.demo.basic;

public class VariableParameter {
	public static void main(String[] args) {
		System.out.println(add(2,3));
		System.out.println(add(2,3,5));
		System.out.println(add(2,3,6,7));
	}
	
	public static int add(int x,int ... args){
		
		int sum=x;
		
		for(int m=0;m<args.length;m++){
			sum+=args[m];
		}
		return sum;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值