清单 1. 带有 public 变量的代码 class Test { public int id; protected String name;
Test(){ id = 1; name = "hello world"; } //code }
public class MyClass extends Test{ public void methodIllegalSet(String name){ this.name = name; // this should not be allowed }
public static void main(String[] args){ Test obj = new Test(); obj.id = 123; // this should not be allowed MyClass mc = new MyClass(); mc.methodIllegalSet("Illegal Set Value"); } }
建议 一般来说,应该使用取值方法而不是 public 变量。按照具体问题具体对待的原则,在确定哪些变量特别重要因而应该声明为 private 时,请将编码的方便程度及成本同安全性需要加以比较。清单 2 演示了以下列方式来使之安全的代码:
清单 2. 不带有 public 变量的代码 class Test { private int id; private String name;
Test(){ id = 1; name = "hello world"; } public void setId(int id){ this.id = id; } public void setName(String name){ this.name = name; } public int getId(){ return id; } public String getName(){ return name; } }
让每个类和方法都为 final 不允许扩展的类和方法应该声明为 final。这样做防止了系统外的代码扩展类并修改类的行为。
清单 8. 潜在恶意的 Java 代码 public void unusedMethod(){ // code written to harm the system }
public void usedMethod(){ //unusedMethod(); //code in comment put with bad intentions, //might affect the system if uncommented // int x = 100; // x=x+10; //Code in comment, might affect the //functionality of the system if uncommented }
清单 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 }
影响 请考虑这个示例:某个方法返回一个对敏感对象的内部数组的引用,假定该方法的调用程序不改变这些对象。即使数组对象本身是不可改变的,也可以在数组对象以外操作数组的内容,这种操作将反映在返回该数组的对象中。如果该方法返回可改变的对象,那么事情会变得更糟;外部实体可以改变在那个类中声明的 public 变量,这种改变将反映在实际对象中。