运行时类型的java.util.Map键和值

Isa*_*aac 0 java spring types dependency-injection map

问题:
我试图找到地图的键和值的java类型,但不必迭代地图然后使用instanceof,即使地图是空的也想知道它.
上下文:
CKEditorConfig可以从这里下载(http://ckeditor.com/download)是使用地图实现的.但是你不能使用注入来设置这个地图,因为没有提供setter方法,并且没有提供构造函数来使用构造函数注入来设置它.但是,有五个addConfigValue方法(见下文),我可以使用它来添加这些值.

public void addConfigValue(final String key, final Number value);
public void addConfigValue(final String key, final String value);
public void addConfigValue(final String key, final Boolean value);
public void addConfigValue(final String key, final Map<String, ? extends Object> value);
public void addConfigValue(final String key, final List<? extends Object> value);
Run Code Online (Sandbox Code Playgroud)



我将在我的j2ee/java web应用程序中的几个地方使用ckeditor,所以我想我应该创建一个工厂类,它返回通过某个名称初始化编辑器所需的设置.但我想将这些配置外部化并在spring上下文文件中设置它们.因为我无法创建配置对象,所以我必须使用常规地图,然后使用地图构建配置对象.但我需要在构建对象之前验证来自spring的那些地图.

这是我构建配置对象的方法:

    @SuppressWarnings("unchecked")
    public CKEditorConfig buildConfigFromMap(Map<String, Object> configMap) {
        CKEditorConfig config = new CKEditorConfig();
        for (String key : configMap.keySet()) {
            Object val = configMap.get(key);
            if (val instanceof Number)
                config.addConfigValue(key, (Number) val);
            else if (val instanceof String)
                config.addConfigValue(key, (String) val);
            else if (val instanceof Boolean)
                config.addConfigValue(key, (Boolean) val);
            else if (val instanceof List) {
                config.addConfigValue(key, (List<Object>) val);
            } else if (val instanceof Map) {
                // TODO
            }
            throw new IllegalArgumentException("invalid map value types");
        }
            return config;
    }
Run Code Online (Sandbox Code Playgroud)

正如您可以看到对象是否是地图,我需要能够验证其键是否为字符串.我知道我可以这样做:

} else if (val instanceof Map) {
    for (Object mapKey : ((Map<Object, Object>) val).keySet()) {
    if (!(mapKey instanceof String))
        throw new IllegalArgumentException("invalid map value types");
    }
config.addConfigValue(key, (Map<String, Object>) val);
}
Run Code Online (Sandbox Code Playgroud)

但整个练习让我觉得我做的不对吗?有什么建议?我愿意采用完全不同的方法.我很感激你的意见.

Dav*_*rre 5

这是不可能的,Java泛型在运行时被删除.实际上它们只存在于编译器(和源代码)中.

您无法检查键和值的实际类型,并从中推导出用于Map的泛型.

您只能在您控制的地图的源代码中推断泛型.

在我看来,你想强制Spring只提供Map <String,?>.这是一个解决方法:

public class StringKeyMapEntry { public String key; public Object value; }
Run Code Online (Sandbox Code Playgroud)

注入List <StringKeyMapEntry>或StringKeyMapEntry [](不确定Spring是否可以执行数组)并将其转换为Map <String,?>