有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

安卓字符串到Java类

我正在编写一个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语句可能会很长。那么有没有办法缩短它呢?例如,将字符串转换为类,然后只创建该类的新实例


共 (4) 个答案

  1. # 1 楼答案

    您可以通过Java反射来实现这一点

    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);
    
  2. # 2 楼答案

    可能的办法

    考虑

    • 离开开关箱
    • 是否确实要实例化新的笔刷对象?考虑重用现有的(已经实例化的对象)
    • 设置笔刷实例化后的颜色和大小

    方法:

    当应用程序启动时,初始化地图中的所有笔刷。您可以将笔刷视为应用程序工作所需的依赖项。 按名称选择笔刷时,从贴图中检索该笔刷

    因此,您通常会有BrushMap.get("*<BrushName>*")

    <>你可以考虑将它封装在一个工厂中,这样你就可以在以后找不到它有用的时候,或者改变它的原因。p>

    因此,最终您将拥有: -在笔刷工厂的构造函数中,您可以将所有笔刷加载到贴图中 -BrushFactory中的getBrush方法将从地图中检索对象,并为其设置颜色和大小

    注意事项:

    1. 如果每次都必须有一个新副本,请考虑Prototype design pattern
    2. 对此可能也有一个反射解决方案

    希望这有帮助:)

  3. # 3 楼答案

    您可以使用factory类“隐藏”开关(开关仍然很大,但它在一个地方进行了本地化)

    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);
            ...
         }
    
  4. # 4 楼答案

    这可能是一个性能上的成功,但是你可以使用反射。 比如:

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