Java外部类静态初始化

时间:2017-09-08 13:25:58

标签: java

我有一个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"));
    }
}

3 个答案:

答案 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
}

Demo.

答案 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);
            }
        };