简体   繁体   English

有没有办法使用名称为 class 的字符串调用 class 的 static 方法?

[英]Is there a way to invoke a static method of a class using a string which has the name of the class?

I have an array of strings containing names of classes.我有一个包含类名的字符串数组。 Is it possible to invoke the static methods of the actual class using the 'name of the class' in the string array.是否可以使用字符串数组中的“类名称”调用实际 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();
        }

I could forget about the array of strings and simple use a if-else block to invoke them.我可以忘记字符串数组并简单地使用 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);

But I will keep implementing other sorts and variations of them in future and every time I will have to make changes in multiple places(The above if-else loop, the help message of my program).但我将在未来继续实现它们的其他种类和变体,每次我都必须在多个地方进行更改(上面的 if-else 循环,我的程序的帮助消息)。 If the former approach is possible then I'll just have to insert an extra string to the array every time.如果前一种方法可行,那么我只需每次都向数组中插入一个额外的字符串。

The better way to implement this would be to create a common interface for your sorting algorithms:实现这一点的更好方法是为您的排序算法创建一个通用接口:

interface SortingAlgorithm {
    public void sort(Comparable[] a);
};

Then have all your algorithms implement that interface:然后让所有算法实现该接口:

class InsertionSort implements SortingAlgorithm {
    public void sort(Comparable[] a) {
        // sort here using insertion-sort
    }
};

and make the parameter to your method take an implementation of the interface:并使您的方法的参数采用接口的实现:

public static double timeTheRun(SortingAlgorithm alg, Comparable[] a) {
    // all the setup
    alg.sort(a);
    // all the post-processing
}

You would then call that method like this:然后,您将像这样调用该方法:

timeTheRun(new InsertionSort(), data);

This has the disadvantage that you cannot make the sorting-routine a static method, though.但是,这样做的缺点是您不能将排序例程设为 static 方法。

Alternative If you insist on static methods, make your routine take a class-object as parameter:替代方案如果您坚持使用 static 方法,请让您的例程将类对象作为参数:

public static double timeTheRun(Class algClass, Comparable[] a) {
    // all the setup
    algClass.getMethod("sort", Comparable[].class).invoke(null, a);
    // all the post-processing
}    

Note that you will either have to add a try-catch-block or a throws declaration for the various exceptions that the reflection methods can throw.请注意,您必须为反射方法可能抛出的各种异常添加 try-catch-block 或 throws 声明。 Then you can call it like this:然后你可以这样称呼它:

timeTheRun(InsertSort.class, data);

Yes, this is possible via reflection.是的,这可以通过反射实现。

Method method = Class.forName(alg).getMethod("sort", Comparable[].class);
method.invoke(null, a);

However, using reflection is not a very clean approach.但是,使用反射不是一个非常干净的方法。 You should consider changing your code to have your sorting algorithms implementing an interface containing this sort method.您应该考虑更改代码以使您的排序算法实现包含此排序方法的接口。 That way you could directly invoke the sort method in a clean way.这样你就可以直接以一种干净的方式调用 sort 方法。

Yes, what you need is the factory pattern .是的,您需要的是工厂模式

Make a common interface shared between the sort algorithms.使排序算法之间共享一个公共接口。 Then make a factory object that returns the right algorithm based on the input.然后制作一个工厂 object 根据输入返回正确的算法。 You can input a enum , string , .class , whatever you like.您可以输入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
}

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

相关问题 动态生成名称的类的调用方法 - Invoke method of a class which name is generated dynamically 是否有从静态方法调用类方法的“最佳”方法? - Is there a “best” way to invoke a class method from a static method? 如何使用method.invoke(-,-)从类中调用字符串 - How to invoke a string from a class using method.invoke(-,-) 有没有办法检查一个类是否有一个方法,然后在已经存在的对象实例上调用它? - Is there a way to check if a class has a method and then invoke it on an already existing instance of the object? Java-如何以类名和方法名作为字符串从另一个类调用方法 - Java - How to invoke a method from another class, with the class name and method name as a string 在存储在var中的Java类上调用静态方法 - Invoke a static method on a Java class stored in a var 在具有静态初始化程序可接受/惯用的类中使用空静态方法? - Is using an empty static method in a class that has a static initializer acceptable/idiomatic? 如何动态调用基类中由字符串值指定的子类方法? - How to invoke a method of child class dynamically which specified by string value in base class? 调用在其超级类中实现的类的方法 - Invoke a method of a class which is implemented in her supperclass class 如何调用具有由参数定义的名称的方法? - How can a class call for a method which has a name defined by the argument?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM