[英]Is there a way to invoke a static method of a class using a string which has the name of the class?
我有一个包含类名的字符串数组。 是否可以使用字符串数组中的“类名称”调用实际 class 的 static 方法。
public class SortCompare {
// There are classes called 'Insertion', 'Selection' and 'Shell' which have a
// method called 'sort'
private static String[] algorithm = { "Insertion", "Selection", "Shell"};
public static double timeTheRun(String alg, Comparable[] a) {
for (int i = 0; i < algorithm.length; i++)
if (alg.equalsIgnoreCase(algorithm[i])) {
Stopwatch timer = new Stopwatch();
// I want to invoke one of Insertion.sort(), Selection.sort()
// or Shell.sort() depending on the value of 'alg' here
break;
}
return timer.elapsedTime();
}
我可以忘记字符串数组并简单地使用 if-else 块来调用它们。
if (alg.equals("Insertion"))
Insertion.sort(a);
else if (alg.equals("Selection"))
Selection.sort(a);
else if (alg.equals("Shell"))
Shell.sort(a);
但我将在未来继续实现它们的其他种类和变体,每次我都必须在多个地方进行更改(上面的 if-else 循环,我的程序的帮助消息)。 如果前一种方法可行,那么我只需每次都向数组中插入一个额外的字符串。
实现这一点的更好方法是为您的排序算法创建一个通用接口:
interface SortingAlgorithm {
public void sort(Comparable[] a);
};
然后让所有算法实现该接口:
class InsertionSort implements SortingAlgorithm {
public void sort(Comparable[] a) {
// sort here using insertion-sort
}
};
并使您的方法的参数采用接口的实现:
public static double timeTheRun(SortingAlgorithm alg, Comparable[] a) {
// all the setup
alg.sort(a);
// all the post-processing
}
然后,您将像这样调用该方法:
timeTheRun(new InsertionSort(), data);
但是,这样做的缺点是您不能将排序例程设为 static 方法。
替代方案如果您坚持使用 static 方法,请让您的例程将类对象作为参数:
public static double timeTheRun(Class algClass, Comparable[] a) {
// all the setup
algClass.getMethod("sort", Comparable[].class).invoke(null, a);
// all the post-processing
}
请注意,您必须为反射方法可能抛出的各种异常添加 try-catch-block 或 throws 声明。 然后你可以这样称呼它:
timeTheRun(InsertSort.class, data);
是的,这可以通过反射实现。
Method method = Class.forName(alg).getMethod("sort", Comparable[].class);
method.invoke(null, a);
但是,使用反射不是一个非常干净的方法。 您应该考虑更改代码以使您的排序算法实现包含此排序方法的接口。 这样你就可以直接以一种干净的方式调用 sort 方法。
是的,您需要的是工厂模式。
使排序算法之间共享一个公共接口。 然后制作一个工厂 object 根据输入返回正确的算法。 您可以输入enum
、 string
、 .class
,无论您喜欢什么。
public interface Sort {
void sort(Comparable[] a)
}
public class SortFactory {
public static sort getSorter(SortType type) {
if (type == SortType.INSERTION)
return new InsertionSort();
if (type == SortType.SELECTION)
return new SelectionSort();
if (type == SortType.SHELL)
return new ShellSort();
}
}
public enum SortType {
INSERTION,
SELECTION,
SHELL
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.