-1

在新课程中我需要什么类型的过程来“阅读”下面这个课程中的所有颜色?我使用该类为组件设置颜色并喜欢它。但是现在是时候让我的应用程序右键单击面板并更改背景颜色了。

在继续使用这些颜色时,是什么让我在正确的方向上开始编码:ColorFactory.java

我刚刚开始考虑向类添加一个新方法,例如:

public Map<String, Color> getColorMapValues(){

    return colorMap;
    //
}
4

2 回答 2

1

您可以通过反射访问颜色图。我不保证以下代码,因为我手头没有 IDE,但这应该可以解决问题:

private static Map<String, Color> getColorMap() throws Exception {
    Field colorMapField = ColorFactory.class.getDeclaredField("colorMap");
    colorMapField.setAccessible(true);
    return (Map<String, Color>) colorMapField.get(ColorFactory.getInstance());
}

然后您可以查询返回的颜色图以按名称获取颜色:

Map<String, Color> colorMap = getColorMap();
Color yellow = colorMap.get("yellow");

如果你想修改颜色图,只需用上面的方法检索它,put()“任何你喜欢的颜色”(是的,Pink Floyd 参考!),然后调用这个方法:

public void setColorMap(Map<String, Color> colorMap) throws Exception {
    Field colorMapField = ColorFactory.class.getDeclaredField("colorMap");
    colorMapField.setAccessible(true);
    colorMapField.set(ColorFactory.getInstance(), colorMap);
}

请注意,这对于类的同步策略是非常危险的,但如果您不使用多个线程发送垃圾邮件,它应该可以工作。

于 2012-08-02T23:01:02.880 回答
1

由于在这种情况下您可以控制源代码,因此最好重构类以满足您的需求而不是使用反射(这不仅昂贵,而且根据您的安全策略被禁止)。

常用的技术是Holder pattern. 有关更多信息,请参阅 Joshua Bloch 的 Effective Java(第 2 版)第 71 条。我们还可以通过使用线程安全的非阻塞结构来避免读取同步,即java.util.concurrent.ConcurrentHashMap.

public class ColorFactory {
    private static class ColorFactoryHolder {
        // creates on instantiation of ColorFactoryHolder
        // synchronization is baked into the JVM, but won't be created until
        // the class is used, see JLS 12.4.1
        static final ColorFactory instance = new ColorMap();
    }
    public static ColorFactory getInstance() { return ColorFactoryHolder.instance; }
    // concurrent hash map - all operations are thread safe
    Map<String,Color> colormap = new ConcurrentHashMap<String,Color>();
    private final Object lock = new Object();
    private ColorFactory() {
        colormap.add("blue",new Color(0,0,255));
        // rest of colors here
    }
    public Color getColor(String spec) {
        if(colormap.containsKey(spec)) return colormap.get(spec);
        // don't synchronize externally - Bloch et al, item 70
        synchronized(lock) { 
            // double check idiom - not broken, as map is thread safe
            if(colormap.containsKey(spec)) return colormap.get(spec);
            Color color = parse(spec); // parse method can be extracted from old code
            colormap.put(spec,color);
            return color;
        }
    }
    private static Color parse(String spec) {
        // parse the color spec here
    }    
}

事实上,因为解析操作可能非常非常快(与同步相比),我们可以完全取消同步。所以我们最终可能会多次解析这个值——这并不是一个大问题,因为每次结果都是一样的。见布洛赫等人。项目 69 了解更多信息。

public class ColorFactory {
    private static class ColorFactoryHolder {
        // same as above, snipped for brevity
    }
    public static ColorFactory getInstance() { return ColorFactoryHolder.instance; }
    // requires ConcurrentMap reference to get putIfAbsent(K,V) method
    ConcurrentMap<String,Color> colormap = new ConcurrentHashMap<String,Color>();
    // private final Object lock = new Object(); - removed
    private ColorFactory() {
        colormap.add("blue",new Color(0,0,255));
        // rest of colors here
    }
    public Color getColor(String spec) {
        Color result = colormap.get(spec);
        if(result == null) {         
            result = parse(spec); // may parse multiple times, but still
                                  // cheaper than synchronization
            colormap.putIfAbsent(spec,result);            
        }
        return result
    }
    private static Color parse(String spec) {
        // parse the color spec here
    }    
}
于 2012-08-03T16:04:59.323 回答