package your.package.name.here;
import java.io.ObjectInputStream;
/**
* A serialization-compatible mock for {@link java.util.EnumMap} that uses an equal {@link #serialVersionUID} and a
* compatible set of fields. When de-serializing an {@link java.util.EnumMap} instance into an instance of this class,
* e.g., by overriding {@link ObjectInputStream}'s {@link ObjectInputStream#resolveClass} method such that it delivers
* this class instead of {@link java.util.EnumMap}, the fields are made accessible through getters; in particular,
* {@link #getKeyType()} reveals the original {@link java.util.EnumMap}'s key type, even if the map is empty.<p>
*
* The {@link EnumMap#getEnumMapKeyType(java.util.EnumMap)} method can be used to determine the key type of any
* {@link java.util.EnumMap}, even if it's empty.
*/
class EnumMap<K extends Enum<K>, V> extends java.util.EnumMap<K, V> {
private final Class<K> keyType;
private transient K[] keyUniverse;
private transient Object[] vals;
private transient int size = 0;
private static final long serialVersionUID = 458661240069192865L;
EnumMap(Class<K> c) {
super(c);
keyType = null;
}
public K[] getKeyUniverse() {
return keyUniverse;
}
public Object[] getVals() {
return vals;
}
public int getSize() {
return size;
}
public Class<K> getKeyType() {
return keyType;
}
/**
* Reconstitute the <tt>EnumMap</tt> instance from a stream (i.e., deserialize it).
*/
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
// Read in the key type and any hidden stuff
s.defaultReadObject();
// Read in size (number of Mappings)
int size = s.readInt();
// Read the keys and values, and put the mappings in the HashMap
for (int i = 0; i < size; i++) {
s.readObject(); // key
s.readObject(); // value
}
}
}
3条答案
按热度按时间rt4zxlrg1#
如果Map不为空,可以检索一个键并检查其类,否则只能通过反射访问EnumMap的
keyType
私有字段(该字段不通过公共API公开)。在第一种情况下,您可以执行以下操作:
在第二种情况下(显然也适用于非空枚举),您可以用途:
如果
EnumMap
的内部实现发生变化,这可能会中断,最好找到一种方法来满足您的需求。mmvthczy2#
如果
EnumMap
不为空,则可以使用如果ENUM包含具有特定于常量的实现的方法,则
getClass()
不起作用。如果
EnumMap
为空,则可以使用反射,如@assylias的答案所示。另一种方法是子类化
EnumMap
并编写public
getter。7lrncoxx3#
如果你不能将
EnumMap
子类化,序列化为一个ObjectOutputStream
,并用一个特殊的ObjectInputStream
反序列化,这个特殊的ObjectInputStream
将EnumMap
类描述符解析为你自己的EnumMap
子类。你的子类必须有与java.util.EnumMap
相同的serialVersionUID
,并且必须有一个简单的名称EnumMap
,而不是一个内部类。而是可以存在于任何封装中。下面是这样一个
EnumMap
子类的示例:注意字段的公共getter,通过它,你可以实现一个小实用程序,提供专门的ObjectInputStream,然后从专门的EnumMap示例中获取键类型,如下所示:
然后,您应该能够使用类似
EnumMapUtil.getKeyType(myEmptyEnumMap)
的内容,它返回枚举的Class
对象,然后您可以在该对象上调用getEnumConstants()
。