深入浅出J2SE 5.0 枚举类型(二)

2014-11-24 01:45:27 · 作者: · 浏览: 7
a.lang.Class

那么,Class并不是Collections API,你的大脑神元经将怎么办呢?可以观察Foo.class这个静态属性,其返回的不再是class,而是Class

Class的类型参数告诉用户其究竟代表是那个类型,允许用户在不cast的情况下就调用Class的某些方法。

以newInstance() 和cast()为例,两者都能返回一个类型确定为T的对象。

Java代码

Class c1 = Date.class;

Class c2 = Date.class;

Date d1 = c1.newInstance();; // 新的用法,不再有ClassCastException

Date d2 = (Date); c2.newInstance();; // 过去的用法

Object o = d1;

// 不再需要手工的cast

// 必要的时候抛出ClassCastException

Date d3 = c1.cast(o);;

// 过去的用法,需要手工cast

Date d4 = (Date); o;

Class c1 = Date.class;

Class c2 = Date.class;

Date d1 = c1.newInstance();; // new style, no potential ClassCastException

Date d2 = (Date); c2.newInstance();; // old style

Object o = d1;

// no need to do a manual cast, the cast(); method

// throws the ClassCastException if necessary

Date d3 = c1.cast(o);;

// old style, need to do a manual cast

Date d4 = (Date); o;

public class Foo { // (A);

//...

}

Foo f1 = ...; // (B);

Foo f2 = ...; // (C);

Java代码

Class c1 = Date.class;

Class c2 = Date.class;

Date d1 = c1.newInstance();; // 新的用法,不再有ClassCastException

Date d2 = (Date); c2.newInstance();; // 过去的用法

Object o = d1;

// 不再需要手工的cast

// 必要的时候抛出ClassCastException

Date d3 = c1.cast(o);;

// 过去的用法,需要手工cast

Date d4 = (Date); o;

Class c1 = Date.class;

Class c2 = Date.class;

Date d1 = c1.newInstance();; // new style, no potential ClassCastException

Date d2 = (Date); c2.newInstance();; // old style

Object o = d1;

// no need to do a manual cast, the cast(); method

// throws the ClassCastException if necessary

Date d3 = c1.cast(o);;

// old style, need to do a manual cast

Date d4 = (Date); o;

public class Foo { // (A);

//...

}

Foo f1 = ...; // (B);

Foo f2 = ...; // (C);

所以,大脑神经元联系建立完毕:Class意味着 类型T的Class实例

类型参数的更多窍门

注意下面的代码

Java代码

abstract class Foo>

{

/** subclasses are forced to return themselves from this method */

public abstract SubClassOfFoo subclassAwareDeepCopy();;

}

class Bar extends Foo {

public Bar subclassAwareDeepCopy(); {

Bar b = new Bar();;

// ...

return b;

}

}

Bar b = new Bar();;

Foo f = b;

Bar b2 = b.subclassAwareDeepCopy();;

Bar b3 = f.subclassAwareDeepCopy();; // 这里是关键,父类直接返回子类的实例,而且不用Cast

Java代码

abstract class Foo>

{

/** subclasses are forced to return themselves from this method */

public abstract SubClassOfFoo subclassAwareDeepCopy();;

}

class Bar extends Foo {

public Bar subclassAwareDeepCopy(); {

Bar b = new Bar();;

// ...

return b;

}

}

Bar b = new Bar();;

Foo f = b;

Bar b2 = b.subclassAwareDeepCopy();;

Bar b3 = f.subclassAwareDeepCopy();; // 这里是关键,父类直接返回子类的实例,而且不用Cast

在这里:

1 Foo的所有subclass 都必须提供一个类型参数给Foo

2 这个类型参数必须是Foo的一个子类

3 Foo的子类把自己当作类型参数传递给Foo

4 Foo具有一个方法,返回SubClassOfFoo. 根据上面的条件,我们可知,对于Foo的任何子类,都必须实现subclassAwareDeepCopy(), 这个方法返回子类本身。

也就是说,我们通过这种方法,使得父类(比如Abstract Factory)可以直接把其子类的类型(而不是父类类型)作为函数的参数或者返回值来使用。

(译者注:条件3并不是强制的,但是是必须的,例如在上例中,我们可以添加Foo的另一个子类

Java代码

class Bar1 extends Foo {

public Bar subclassAwareDeepCopy(); {

return new Bar();;

}

}

Java代码

class Bar1 extends Foo {

public Bar subclassAwareDeepCopy(); {

return new Bar();;

}

}

这里,Bar1并不具备通过subclassAwareDeepCopy