繁体   English   中英

使用字符串实例化一个类

[英]Using a string to instantiate a class

假设我有圆形,矩形和三角形类。

基于数据文件的输入,我想创建适当的对象。 例如,如果shapes.dat的第一行是C.5 0 0 ,我将创建一个半径为5的Circle对象。如果下一行是R.5 3 0 ,我将创建一个长度为5且宽度为Rectangle的对象。 3。

我知道我可以使用基本的if-else逻辑,但是我想知道是否存在一种使用字符串作为实例化新对象的方法。 有点像Python中的exec()方法。 这是描述我想要的代码片段:

    Scanner file = new Scanner (new File("shapes.dat"));
    String s;       

    Map<Character,String> dict = new HashMap<Character,String>();
    dict.put('C', "Circle");
    dict.put('R', "Rectangle");
    dict.put('T', "Triangle");

    while (file.hasNextLine())
    {
        s = file.nextLine().trim();

        String name = dict.get(s.toCharArray()[0]);
        String data = s.split(".")[1];
        String code = name + " x = new " + name + "(data);";

        SYS.exec(code); //???

        ...

    }

我不确定我是否理解正确,似乎还没有人提到这一点:

Map<Character, ShapeFactory> dict = new HashMap<>();
dict.put('C', new CircleFactory());
dict.put('R', new RectangleFactory());
dict.put('T', new TriangleFactory());

...

ShapeFactory factory = dict.get(symbol);
Shape shape = factory.create(data);

您可以利用反射来动态创建实例。

String className = "com.shape.Triangle";
Class classDefinition = Class.forName(className);
Object obj = classDefinition.newInstance();

要么

只需使用if-else创建特定类的实例。

Python中的Exec执行代码。
您可以使用Java执行相同的操作,例如使用javassist。
您可以读取数据文件,编译语句,然后将其插入自己的类中。
但这似乎太过分了。

您也可以使用Java反射,但它会产生脆弱且不清楚的代码。

if else if,我认为应该使用抽象并按对象类型创建工厂类。

它可能看起来像:

Scanner file = new Scanner (new File("shapes.dat"));
String s;       

Map<Character, ShapeBuilder> dict = new HashMap<Character,String>();
dict.put('C', new CircleBuilder());
dict.put('R', new RectangleBuilder());
dict.put('T', new TriangleBuilder());

while (file.hasNextLine()){
    s = file.nextLine().trim();
    char shapeSymbol = ...; // computed from s
    ShapeBuilder builder = dict.get(shapeSymbol);
    Shape shape = builder.build(s);
}

实际上,您可以使用多态来避免if-else语句。 因此,您可以创建实际执行所需的两项工作,匹配一条线并创建一个形状的对象。 因此,您可以使用类似以下代码的内容。

public class Program {

    public static void main() throws FileNotFoundException {
        Scanner file = new Scanner(new File("shapes.dat"));

        while (file.hasNextLine()) {
            String line = file.nextLine().trim();
            Shape shape = new Matches(
                new RectangleMatch(),
                new TriangleMatch(),
                new SquareMatch(),
                new CircleMatch()
            ).map(line);
        }
    }


    public interface ShapeMatch {
        boolean matches(String line);

        Shape shape(String line);
    }


    public static final class RectangleMatch implements ShapeMatch {
        @Override
        public boolean matches(String line) {
            return line.startsWith("R");
        }

        @Override
        public Shape shape(String line) {
            String[] dimensions = line.substring(2).split(" ");
            return new Rectangle(
                Integer.parseInt(dimensions[0]),
                Integer.parseInt(dimensions[1]),
                Integer.parseInt(dimensions[2])
            );
        }
    }


    public static final class CircleMatch implements ShapeMatch {
        @Override
        public boolean matches(String line) {
            return line.startsWith("C");
        }

        @Override
        public Shape shape(String line) {
            return new Circle(Integer.parseInt(line.substring(2, line.indexOf(" "))));
        }
    }


    public interface ShapeMapping {
        Shape map(String line);
    }

    public static final class Matches implements ShapeMapping {
        private final Iterable<ShapeMatch> matches;

        public Matches(ShapeMatch... matches) {
            this(Arrays.asList(matches));
        }

        public Matches(Iterable<ShapeMatch> matches) {
            this.matches = matches;
        }

        @Override
        public Shape map(String line) {
            for (ShapeMatch match : matches) {
                if (match.matches(line)) {
                    return match.shape(line);
                }
            }

            throw new RuntimeException("Invalid shape entry line.");
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM