java黑客帝国代码 黑客帝国矩阵代码( 五 )


}
public void method2(){
try{
if(initialized==true){
//proceed with the business logic
}
else{
throw new Exception("Illegal State Of the object");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
如果对象由逆序列化进行初始化,那么上面讨论的验证机制将难以奏效,因为在该过程中并不调用构造器 。在这种情况下 , 类应该实现 ObjectInputValidation 接口:
清单 10. 实现 ObjectInputValidation
interface java.io.ObjectInputValidation {
public void validateObject() throws InvalidObjectException;
}
所有验证都应该在 validateObject() 方法中执行 。对象还必须调用 ObjectInputStream.RegisterValidation() 方法以为逆序列化对象之后的验证进行注册 。RegisterValidation() 的第一个参数是实现 validateObject() 的对象,通常是对对象自身的引用 。注:任何实现 validateObject() 的对象都可能充当对象验证器,但对象通常验证它自己对其它对象的引用 。RegisterValidation() 的第二个参数是一个确定回调顺序的整数优先级,优先级数字大的比优先级数字小的先回调 。同一优先级内的回调顺序则不确定 。
当对象已逆序列化时 , ObjectInputStream 按照从高到低的优先级顺序调用每个已注册对象上的 validateObject() 。
不要通过名称来比较类
有时候,您可能需要比较两个对象的类,以确定它们是否相同;或者,您可能想看看某个对象是否是某个特定类的实例 。因为 JVM 可能包括多个具有相同名称的类(具有相同名称但却在不同包内的类),所以您不应该根据名称来比较类 。
影响
如果根据名称来比较类,您可能无意中将您不希望授予别人的权利授予了闯入者的类 , 因为闯入者可以定义与您的类同名的类 。
例如 , 请假设您想确定某个对象是否是类 com.bar.Foo 的实例 。清单 11 演示了完成这一任务的错误方法:
清单 11. 比较类的错误方法
if(obj.getClass().getName().equals("Foo"))// Wrong!
// objects class is named Foo
}else{
// object's class has some other name
}
建议
在那些非得根据名称来比较类的情况下,您必须格外小心,必须确保使用了当前类的 ClassLoader 的当前名称空间,如清单 12 中所示:
清单 12. 比较类的更好方法
if(obj.getClass() == this.getClassLoader().loadClass("com.bar.Foo")){
// object's class is equal to
//the class that this class calls "com.bar.Foo"
}else{
// object's class is not equal to the class that
// this class calls "com.bar.Foo"
}
然而,比较类的更好方法是直接比较类对象看它们是否相等 。例如,如果您想确定两个对象 a 和 b 是否属同一个类,那么您就应该使用清单 13 中的代码:
清单 13. 直接比较对象来看它们是否相等
if(a.getClass() == b.getClass()){
// objects have the same class
}else{
// objects have different classes
}
尽可能少用直接名称比较 。
不要使用内部类
Java 字节码没有内部类的概念,因为编译器将内部类转换成了普通类,而如果没有将内部类声明为 private,则同一个包内的任何代码恰好能访问该普通类 。
影响
因为有这一特性,所以包内的恶意代码可以访问这些内部类 。如果内部类能够访问括起外部类的字段 , 那么情况会变得更糟 。可能已经将这些字段声明为 private,这样内部类就被转换成了独立类 , 但当内部类访问外部类的字段时 , 编译器就将这些字段从专用(private)的变为在包(package)的作用域内有效的 。内部类暴露了已经够糟糕的了 , 但更糟糕的是编译器使您将某些字段成为 private 的举动成为徒劳 。

推荐阅读