这是
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]; } } }
虽然,与复制任何与互联网相关的安全性一样,但需要注意.我绝不是专家.