RTTI:
* 类加载器, 类加载器链,只有一个原生类加载器加载可信类(本地);
* 所有的类都是在对其第一次使用时,动态加载到JVM中;Java程序在运行之前并非完全加载,各个部分在必需时才加载;
* 构造器也是类的静态方法;
* static 子句是在类首次加载时进行的,应放置类加载时就需要执行的语句;
* Class.forName()会导致类的加载,而类字面常量不会,编译期常量(static final)不需要类初始化就可以读取;
* 使用newInstance()来创建的类,必须有默认的构造器(无参数构造器);
* 基本类型并非继承自Object;
泛化的Class引用:
* Class<? extends className>,创建一个范围,可以进行编译器的类型检查;
模版设计模式:
* 设置一个存储Class对象的List;由random方法产生随机数作为List的索引;通过newInstance()实例化;
* instanceof只可将其与命名类型进行比较,而不能与Class对象做比较;可通过isInstance()实现动态的instanceof();
instanceof的对象可以为派生类对象,考虑了继承关系;getClass()==,该方法不考虑继承关系;
工厂设计模式:
public interface Factory<T> { T create(); }
class Filter{
public static class Factory implements Factory<Filter>{
public Filter create(){
return new Filter();
}
}
}
* 使用了协变返回类型;
反射:
* RTTI限制:某个对象的确切类型在编译时必须已知,这样才能使用RTTI识别;若该对象在程序空间之外(网络),则不能使用RTTI;
* RMI,要实现远程方法调用;
* RTTI与反射的区别:RTTI在编译时打开和检查.class文件,反射是在运行时打开和检查.class文件;
动态代理设计模式:
空对象思想:
* 标记接口,通过判断某个对象是否为标记接口的实例而确定是否为空对象;
public interface Null{}
public class Person{}
public class NullPerson extends Person implements Null{}
Person np=new NullPerson();
if(np instanceof Null){
//~
}
* 空对象的思想避免了一部分繁琐的比较;
命令设计模式:
public interface Operation{
String description();
void command();
}
public interface Robot{
String name();
String model();
List<Operation> operations();
}
public class SnowRemovalRobot implements Robot{
String name(){~};
String model(){~};
List<Operation> operations(){
return Arrays.asList(
new Operation(){
//~; //implements description() & command();
},
new Operation(){
//~; //implements description() & command();
},
new Operation(){
//~; //implements description() & command();
}
);
}
}
* interface关键字的一个重要目标就是允许程序员隔离构件,降低耦合性,但是通过反射以及RTTI,耦合性还是会传播出去;
* 解决方法:1. 程序员决定使用实际的类而不是接口的话,需要对自己负责; 2. 设置包访问权限;
* 但是通过反射机制,仍旧可以到达并调用所有方法以及访问和修改域,包括private。通过getDeclaredMethod()以及setAccessible(true)实现;