1.类型转换前先做检查
1)传统的类型转换,执行错误的类型转换,会抛出ClassCastException。
2)代表对象的类型的Class对象,通过查询Class对象可以获取运行时所需的信息。
3)IllegalAccessException表示违反Java安全机制。
4)向上转型可以不显式,向下转型要显式。
5)inatanceof只能与命名类型(就是类名)比较,不能与对象比较。
2.注册工厂
使用工厂方法设计模式,将对象的创建工作交给类自己去完成。工厂方法可以被多态地调用,从而为你创建恰当类型的对象。避免每多一个类,就要往类字面常量列表手动里加一个类引用。在以下示例中,工厂方法就是Factory接口中的create()方法,例如:
public interface Factory<T> { T create(); }
泛型参数T使得create()可以在每种Factory实现中返回不同的类型。
工厂类接口,泛型,并使用create()使子类自己生成类对象
class Part {
public String toString() {
return getClass().getSimpleName();
}
static List<Factory<? extends Part>> partFactories = new ArrayList<Factory<? extends Part>>();
static { // 类型列表,生成内部类,加载类
partFactories.add(new FuelFilter.FactoryImpl());
partFactories.add(new AirFilter.FactoryImpl());
partFactories.add(new CabinAirFilter.FactoryImpl());
partFactories.add(new OilFilter.FactoryImpl());
partFactories.add(new FanBelt.FactoryImpl());
partFactories.add(new PowerSteeringBelt.FactoryImpl());
partFactories.add(new GeneratorBelt.FactoryImpl());
}
private static Random rand = new Random(47);
public static Part createRandom() { // 随机返回类型列表的某个外部类对象
int n = rand.nextInt(partFactories.size());
return partFactories.get(n).create();
}
}
private static Random rand = new Random(47);
public static Part createRandom() { //随机返回类型列表的某个外部类对象
int n = rand.nextInt(partFactories.size());
return partFactories.get(n).create();
}
}
public class Filter extends Part {}
public class FuelFilter extends Filter {
public static class FactoryImpl implements Factory<FuelFilter> { // Factory重名,需要用全限定类名表示接口类
public FuelFilter create() {
return new FuelFilter();
}
}
}
public class AirFilter extends Filter {
public static class FactoryImpl implements Factory<AirFilter> {
public AirFilter create() {
return new AirFilter();
}
}
}
public class CabinAirFilter extends Filter {
public static class FactoryImpl implements Factory<CabinAirFilter> {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
public class OilFilter extends Filter {
public static class FactoryImpl implements Factory<OilFilter> {
public OilFilter create() {
return new OilFilter();
}
}
}
public class Belt extends Part {
}
class FanBelt extends Belt {
public static class FactoryImpl implements Factory<FanBelt> {
public FanBelt create() {
return new FanBelt();
}
}
}
public class GeneratorBelt extends Belt {
public static class FactoryImpl implements Factory<GeneratorBelt> {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
public class PowerSteeringBelt extends Belt {
public static class FactoryImpl implements Factory<PowerSteeringBelt> {
public PowerSteeringBelt create() {
return new PowerSteeringBelt();
}
}
}
public class RegisteredFactories {
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
System.out.println(Part.createRandom());
}
}
/* Output:
GeneratorBelt
CabinAirFilter
GeneratorBelt
AirFilter
PowerSteeringBelt
CabinAirFilter
FuelFilter
PowerSteeringBelt
PowerSteeringBelt
FuelFilter
并非所有在继承结构中的类都应该被实例化,在本例中,Filter和Belt只是分类标识,因此不应该创建它们的实例,而只应该创建它们的子类的实例。如果某个类应该由createRandom()方法创建,那么它就包含一个内部的FactoryImpl类。
3.instanceof与Class的等价性
在查询类型信息时,以instanceof的形式(即instanceof的形式或isInstance()的形式,它们产生相同的结果)与直接比较Class对象有一个很重要的差别。类引用.equals(类引用) 和 类引用==类引用结果也一样,instanceof保持了类型的概念,包括派生类,== 比较实际的Class对象,没有考虑继承。