那么,Class并不是Collections API,你的大脑神元经将怎么办呢?可以观察Foo.class这个静态属性,其返回的不再是class,而是Class
Class的类型参数告诉用户其究竟代表是那个类型,允许用户在不cast的情况下就调用Class的某些方法。
以newInstance() 和cast()为例,两者都能返回一个类型确定为T的对象。
Java代码
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
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
//...
}
Foo
Foo
Java代码
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
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
//...
}
Foo
Foo
所以,大脑神经元联系建立完毕: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
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
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