字符串到类Java

时间:2015-10-29 03:07:50

标签: java android class

我正在编写一个具有绘图功能的Android应用,并允许用户选择不同的画笔来绘制。有一次,当刷子更换时,我有以下方法:

public Brush newBrush(String className){
    Brush currentBrush;
    switch (className){
        case "StandardBrush":
            currentBrush = new StandardBrush(currentColor, currentSize);
            break;
        case "SquareBrush":
            currentBrush = new SquareBrush(currentColor, currentSize);
            break;
        case "Highlighter":
            currentBrush = new Highlighter(currentColor, currentSize);
            break;
        case "AirBrush":
            currentBrush = new AirBrush(currentColor, currentSize);
            break;
        case "PaintBrush":
            currentBrush = new PaintBrush(currentColor, currentSize);
            break;
        case "CalligraphicBrush":
            currentBrush = new CalligraphicBrush(currentColor, currentSize);
            break;
        case "VanishingBrush":
            currentBrush = new VanishingBrush(currentColor, currentSize);
            break
    }
    return currentBrush;
}

如果我稍后选择添加更多选项,则此switch语句可能会变得很长。那么有没有办法缩短它?比如将字符串转换为Class然后只创建该类的新实例?

4 个答案:

答案 0 :(得分:2)

它可能会受到性能影响,但您可以使用反射。 类似的东西:

 return Class.forName(className).getConstructors()[0].newInstance(color, size);

答案 1 :(得分:0)

您可以使用工厂类来隐藏"开关(它仍然很大,但它在一个地方局部化)

class BrushFactory()
{
    static Brush getBrush(string type, int color, int size)
    {
        switch (className){
        case "StandardBrush":
            return new StandardBrush(currentColor, currentSize);
        case "SquareBrush":
            return new SquareBrush(currentColor, currentSize);
        ...
     }

答案 2 :(得分:0)

您可以通过Java Reflection执行此操作。

public Brush newBrush(String className){
    try {
        Class<? extends Brush> brushClass = (Class<? extends Brush>)Class.forName(className);
        Constructor<? extends Brush> constructor = brushClass == null ? null : brushClass.getConstructor(Color.class, int.class); // Argument types need to be changed to whatever currentColor and currentSize are
        return constructor == null ? null : constructor.newInstance(currentColor, currentSize);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

编辑:上面假设没有包,你可能需要预先添加。如果它们位于同一个包中,则如何执行此操作:

String p = getClass().getName();
p = p.substring(0, p.lastIndexOf('.') + 1);
Class.forName(p + className);

答案 3 :(得分:0)

一种可能的方法

考虑

  • 远离开关盒
  • 您真的想要实例化一个新的Brush对象吗?考虑重用现有的(已经实例化的对象)
  • 设置画笔实例化后的颜色和大小?

方法:

当您的应用开始初始化地图中的所有画笔时。您可以将画笔视为应用程序执行其工作所需的依赖项。 按名称选择画笔时,请从地图中检索画笔。

所以你通常会BrushMap.get("*<BrushName>*")

您可以考虑将其封装在工厂中,以便以后如果您认为方法无用或想要因任何原因进行更改,您仍然可以更改方法。

所以最后你会得到:   - 在BrushFactory的构造函数中,您将所有画笔加载到地图中   - BrushFactory中的getBrush方法将从map中检索对象并为其设置颜色和大小

备注:

  1. 如果每次都必须有新副本,请考虑Prototype design pattern
  2. 这也可能是一种反思解决方案。
  3. 希望这会有所帮助:)