gpt4 book ai didi

java - 使用反射来使用特定的类构造函数并创建新对象

转载 作者:行者123 更新时间:2023-12-01 19:33:15 25 4
gpt4 key购买 nike

我有两个类。

public class Shape1 extends javafx.scene.shape.Path {

public Shape1(PathElement... elements) {
super(elements);
}
}

public class Shape2 extends javafx.scene.shape.Path {

public Shape2(PathElement... elements) {
super(elements);
}
}

它们不一样。它们有不同的字段和方法,但为了简单起见我没有提及它们。

我为每种类型的对象创建两个数组,并且只需要使用一种方法来创建它们。

ArrayList<Shape1> first_shapes = create_array(50, 50, 100, 100, Class.forName("example3.Shape1"));
ArrayList<Shape2> second_shapes = create_array(50, 100, 100, 150, Class.forName("example3.Shape2"));

public static ArrayList create_array(int X1, int Y1, int X2, int Y2, Class my_class) {
var shapes = new ArrayList<>();
shapes.add(my_class.getConstructor(PathElement[].class).newInstance(new MoveTo(X1, Y1), new LineTo(X2, Y2)));
...
return shapes;
}

该代码有两个问题。

  1. 类定义不合适,因为更改类名或包名时它将不起作用,必须手动更改。

  2. 实际上,它根本不起作用,因为当您向数组添加对象时它会崩溃。

奇怪的是,在上面的表单中它会显示错误。

参数数量错误

但是如果我只使用一个参数,

shapes.add(my_class.getConstructor(PathElement[].class).newInstance(new MoveTo(X1, Y1)));

它将显示错误。

参数类型不匹配

这是解决我的问题的唯一方法。否则我就必须改变整个算法。

请帮忙

谢谢

最佳答案

首先,启用所有编译器警告,并注意它们。你永远不想使用ClassArrayList没有泛型类型;请参阅What is a raw type and why shouldn't we use it? .

关于反射的最佳策略是避免使用反射。

  • 反射很慢。它不太可能被即时编译器优化。
  • 反射是不安全的。编译器无法检查您是否犯了错误,例如拼写错误或方法签名错误。
  • 反射很难阅读。您始终需要能够在以后理解和维护您的代码。在专业领域,其他人可能需要维护您的代码,可能在您离开很久之后。

不要使用反射,而是将每个构造函数视为 function 。具体来说,该函数将 PathElements 序列作为输入,并生成特定类的新实例作为输出。在Java中,写为:

Function<PathElement[], S>

哪里S本身定义为 <S extends Path> ,即继承自 Path 的已知类型。

您可以将此已知类型和已知构造函数传递给您的方法:

public static <S extends Path> ArrayList<S> create_array(
int X1, int Y1, int X2, int Y2,
Function<PathElement[], S> shapeConstructor) {

var shapes = new ArrayList<S>();
shapes.add(shapeConstructor.apply(new PathElement[] {
new MoveTo(X1, Y1), new LineTo(X2, Y2)
}));
//...
return shapes;
}

现在您拥有的代码既是类型安全的,又能够在编译时捕获任何拼写或语法错误。

此方法的调用如下所示:

ArrayList<Shape1> shapeList1 = create_array(10, 10, 50, 50, Shape1::new);
ArrayList<Shape2> shapeList2 = create_array(20, 20, 80, 80, Shape2::new);

关于java - 使用反射来使用特定的类构造函数并创建新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58867618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com