0

问题:
我正在尝试查找映射的键和值的 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);



我将在我的 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;
    }

正如你所看到的,如果对象是一个地图,我需要能够验证它的键是否是一个字符串。我知道我可以做这样的事情:

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

但整个练习让我觉得我做的不对?有什么建议么?我愿意使用完全不同的方法。感谢您的意见。

4

2 回答 2

5

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

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

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

在我看来,您想强制 Spring 仅提供 Map<String, ?>。这是一种解决方法:

public class StringKeyMapEntry { public String key; public Object value; }

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

于 2012-11-09T15:36:02.537 回答
0

您有许多由字符串引用的设置......我会使用一种方法并将签名更改为此。

public void configure(final Map<String, ? extends Object> map);

然后对每个设置做你想做的事情,你可以直接调用每个设置或循环遍历它。

于 2012-11-09T15:29:17.667 回答