您应该使用格式字符串"#%06X" 而不是"%06x#"。首先,它将# 字符放在您真正想要的位置,其次,它生成一个大写的十六进制字符串,无需在结果上调用toUpperCase()。
但是,与显式值映射相比,您的反射操作节省了多少?当我遍历Color 的所有字段时,例如通过
final int constant = Modifier.STATIC | Modifier.FINAL;
Map<String,Integer> m = new HashMap<>();
for(Field f: Color.class.getFields()) try {
if((f.getModifiers() & constant) == constant && f.getType() == Color.class)
m.put(f.getName().toLowerCase().replace('_', ' '),
((Color)f.get(null)).getRGB() & 0x00FFFFFF);
} catch(ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
m.forEach((name,rgb) -> System.out.printf("map.put(\"%s\", \"#%06X\");%n", name, rgb));
我明白了
map.put("magenta", "#FF00FF");
map.put("pink", "#FFAFAF");
map.put("green", "#00FF00");
map.put("black", "#000000");
map.put("yellow", "#FFFF00");
map.put("cyan", "#00FFFF");
map.put("dark gray", "#404040");
map.put("red", "#FF0000");
map.put("orange", "#FFC800");
map.put("gray", "#808080");
map.put("white", "#FFFFFF");
map.put("blue", "#0000FF");
map.put("darkgray", "#404040");
map.put("light gray", "#C0C0C0");
map.put("lightgray", "#C0C0C0");
这不是那么大。因此,当我将该输出复制到一个新代码中时,例如
static final Map<String,String> COLOR_CODES;
static {
Map<String,String> map = new HashMap<>();
map.put("magenta", "#FF00FF");
map.put("pink", "#FFAFAF");
map.put("green", "#00FF00");
map.put("black", "#000000");
map.put("yellow", "#FFFF00");
map.put("cyan", "#00FFFF");
map.put("dark gray", "#404040");
map.put("red", "#FF0000");
map.put("orange", "#FFC800");
map.put("gray", "#808080");
map.put("white", "#FFFFFF");
map.put("blue", "#0000FF");
map.put("darkgray", "#404040");
map.put("light gray", "#C0C0C0");
map.put("lightgray", "#C0C0C0");
COLOR_CODES = Collections.unmodifiableMap(map);
}
static String getHexaColor(String colorName) {
return COLOR_CODES.getOrDefault(colorName.toLowerCase(), "");
}
结果很简单,无需反射。维护将独立于生成此版本的反射代码,因为向映射添加新常量比向 java.awt.Color 类添加新常量(重新运行反射代码)更简单。
唯一具有更大灵活性的替代方法是使用properties 文件,它允许在不重新编译应用程序的情况下更新地图。改用上面的代码来生成属性文件很容易,但另一方面,互联网上有足够多的即用型文件具有更多颜色。例如,您可以直接从 w3.org 复制基于 VGA 的网页颜色,而 this extended list 则需要将高级搜索和替换引入属性格式。