我有一个包含类名称的字符串数组。是否可以使用字符串数组中的“类名”来调用实际类的静态方法。
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循环,我程序的帮助信息)。如果前一种方法是可行的,那么我每次只需要在数组中插入一个额外的字符串。
答案 0 :(得分:6)
实现这一点的更好方法是为排序算法创建一个通用接口:
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);
这样做的缺点是你无法使sort-routine成为静态方法。
备用如果您坚持使用静态方法,请使您的例程将类对象作为参数:
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);
答案 1 :(得分:4)
是的,这可以通过反思实现。
Method method = Class.forName(alg).getMethod("sort", Comparable[].class);
method.invoke(null, a);
然而,使用反射并不是一种非常干净的方法。您应该考虑更改代码以使排序算法实现包含此排序方法的接口。这样你就可以直接调用sort方法。
答案 2 :(得分:0)
是的,您需要的是factory pattern。
在排序算法之间共享一个公共接口。然后根据输入创建一个返回正确算法的工厂对象。您可以输入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
}