我有一个Java静态初始化问题。我想要做的是使用泛型常量进行一些类型检查,并在类型和类型名称之间进行转换。所以我在接口MC中有一些类型的常量,在内部类Type中有一个哈希映射,用于将名称转换为类型。现在,当我调用
MC.Type.getValue("MInteger")时,内部类Type被初始化,但不是外部类MC中的静态常量,因此返回值为
null
。如何让Java初始化这些常量?我可以做
static { Type<?> dummy = MC.MBoolean; }在类Type中
但是没有更好的方法来做到这一点。或者我完全错了。
import java.util.HashMap;
import java.util.Map;
interface MC {
public static final Type<Boolean> MBoolean = new Type<>("MBoolean");
public static final Type<Integer> MInteger = new Type<>("MInteger");
public static class Type<T> {
private static final Map<String, Type<?>> types = new HashMap<>();
private final String name;
private Type(String name) {
this.name = name;
types.put(name, this);
}
public String getName() {
return name;
}
public static Type<?> getValue(String name) {
return types.get(name);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println(MC.Type.getValue("MInteger"));
MC.MBoolean.getName();
System.out.println(MC.Type.getValue("MInteger"));
}
}
答案 0 :(得分:1)
由于所有Type
个实例都包含在MC
类中,因此解决此问题的一个非常直接的方法是使用Type.types
映射从类的构造函数移动类的注册Type
到其静态初始值设定项:
private static final Map<String, Type<?>> types = new HashMap<>();
static {
types.put(MBoolean.getName(), MBoolean);
types.put(MInteger.getName(), MInteger);
}
private Type(String name) {
this.name = name;
// removed types.put(name, this); from here
}
答案 1 :(得分:1)
您可以使用静态初始化程序块:
private static final Map<String, Type<?>> types = new HashMap<>();
static {
types.put(MC.MBoolean.getName(), MC.MBoolean);
types.put(MC.MInteger.getName(), MC.MInteger);
}
或双支撑初始化:
private static final Map<String, Type<?>> types = new HashMap<>() {{
put(MC.MBoolean.getName(), MC.MBoolean);
put(MC.MInteger.getName(), MC.MInteger);
}};
第一个花括号创建HashMap
的新匿名子类,第二个花括号是实例初始化程序块,它在构造时执行(匿名类的无构造函数)。
答案 2 :(得分:0)
除非您明确调用MC.MBoolean
,否则构造函数不会初始化。所以你最好使用Double brace初始化。
private static final Map<String, Type<?>> types = new HashMap<>() {
{
put(MC.MBoolean.getName(), MC.MBoolean);
put(MC.MInteger.getName(), MC.MInteger);
}
};