有没有办法使用具有类名称的字符串调用类的静态方法?

时间:2011-06-28 07:49:07

标签: java

我有一个包含类名称的字符串数组。是否可以使用字符串数组中的“类名”来调用实际类的静态方法。

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循环,我程序的帮助信息)。如果前一种方法是可行的,那么我每次只需要在数组中插入一个额外的字符串。

3 个答案:

答案 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

在排序算法之间共享一个公共接口。然后根据输入创建一个返回正确算法的工厂对象。您可以输入enumstring.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
}