这是
this question的后续行动.这个解决方案是否具有防水功能?
public final class Thing implements Serializable {
private static final long serialVersionUID = 1L;
private static final Thing[] instances = new Thing[2];
private static int nextOrdinal = 0;
public static final Thing instance0 = new Thing("whatever0");
public static final Thing instance1 = new Thing("whatever1");
private transient final String someState;
public String someMethod() {return someState;}
private final int ordinal;
private Thing(String someState) {
this.someState = someState;
this.ordinal = nextOrdinaL++;
instances[this.ordinal] = this;
}
private Object readResolve() throws ObjectStreamException {
return instances[this.ordinal];
}
}
解决方法
Is this solution watertight?
不.(虽然它可能是足够的,取决于代码的使用方式和位置.)
在第77项中:对于实例控制,首选枚举类型为readResolve(Effective Java,2nd ed),Bloch演示了攻击者如何拥有像您这样的类返回任何值.攻击依赖于手工制作的字节输入,并且能够在目标上运行代码(因此,如果在沙盒环境中使用,某些RMI情况等,则代码可能存在安全风险).我不知道这是否是唯一的攻击 – 它是唯一提到的攻击.解决方案是声明所有字段是瞬态的,但是您遇到了如何存储值的问题.
您可以使用序列化代理模式解决这些问题(书中的第78项 – 每个阅读它的Java程序员都推荐它的原因).
public final class Thing implements Serializable {
private static final long serialVersionUID = 1L;
private static final Thing[] INSTANCES = new Thing[2];
private static int NEXT_ORDINAL = 0;
public static final Thing INSTANCE0 = new Thing(
"whatever0");
public static final Thing INSTANCE1 = new Thing(
"whatever1");
private transient final String someState;
public String someMethod() {
return someState;
}
private final int ordinal;
private Thing(String someState) {
this.someState = someState;
ordinal = NEXT_ORDINAL++;
INSTANCES[ordinal] = this;
}
private Object writeReplace() {
return new ThingProxy(this);
}
private void readobject(ObjectInputStream stream)
throws InvalidobjectException {
throw new InvalidobjectException("Proxy required");
}
private static class ThingProxy implements Serializable {
private static final long serialVersionUID = 1L;
private final int ordinal;
private ThingProxy(Thing t) {
ordinal = t.ordinal;
}
private Object readResolve()
throws ObjectStreamException {
return INSTANCES[ordinal];
}
}
}
虽然,与复制任何与互联网相关的安全性一样,但需要注意.我绝不是专家.