【问题标题】:load a class without knowing name in a specific folder in java在java中的特定文件夹中加载一个类而不知道名称
【发布时间】:2015-07-20 19:42:36
【问题描述】:

我有一个 java 应用程序,它在文件中执行一些操作并发布结果输出。我想添加一个属性,每个使用我的应用程序的人都可以添加他/她的特定操作员。并且知道我想在不知道其名称或方法的情况下加载类。

这是我的班级,我知道可能要添加的班级和方法名称:

public class PathGetter {

public static void main(String[] args) {
    try{
        String AbsolutePath = args[0];
        AbsolutePath += "\\in.txt";

        String SecondFilePath = args[1];
        SecondFilePath += "\\out.txt";

        File file = new File(SecondFilePath);
        file.createNewFile();
        FileWriter writer = new FileWriter(file);

        FileReader fr = new FileReader();
        Object newOp = null;
        String newOpSign="!@#$%^&*";
        Method m = null;

        MathOperations mathOperations = new MathOperationsImpl();

        System.out.println("Do you have new operator? ");
        Scanner scanner1 = new Scanner(System.in); 

        if(scanner1.nextBoolean()==true){
            Scanner scanner2 = new Scanner(System.in);
            System.out.println("Enter operator sign: ");
            newOpSign = scanner2.nextLine();

            File addedClass= new File("E:\\workspace\\940420\\bin");

            URI uri = addedClass.toURI();
            URL[] urls = new URL[]{uri.toURL()};

            ClassLoader classLoader = new URLClassLoader(urls);

            Class clazz = classLoader.loadClass("second.MathOperationsUpdateImpl");   \\I don't know the class name might be added

            newOp = clazz.newInstance();    
            m = newOp.getClass().getMethod("mathOperate", String.class); \\I don't know the method name in added class

        }



        ArrayList<String> answer = new ArrayList<String>();

        for (int i = 0; i < fr.readFile(AbsolutePath).size(); i++) {
            if((fr.readFile(AbsolutePath).get(i)).contains(newOpSign)){

                answer.add(i,  String.valueOf(m.invoke(newOp,(fr.readFile(AbsolutePath).get(i)))));
            }
            else{
                answer.add(i, String.valueOf(mathOperations.mathOperate(fr.readFile(AbsolutePath).get(i))));
            }
        }

        for (int i = 0; i < fr.readFile(AbsolutePath).size(); i++) {
            writer.write(answer.get(i)+ "\r\n");
        }

        writer.close();

        System.out.print("Your File Successfully Created In: " + SecondFilePath);

    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}   
}

【问题讨论】:

  • 我跟不上。你的具体问题是什么?如果您不知道类和/或方法名称,则使用反射是正确的方法(但您已经使用反射)。
  • 这只是我为自己编写的代码,我想更改代码以便可以从用户以我知道的特定路径编写的类中生成对象!但我不知道资格类名称及其方法。我想创建一个可能由我的代码用户添加的类的实例。 (我只知道用户类的路径)
  • 这样你就知道类文件的名称和路径了。使用Class c = Class.forName(&lt;classname") 加载它。你也可以通过反射获得所有可用的方法:Methods[] m = c.getMethods()。例如,您可以通过m[0].getName() 获取有关这些方法的更多信息。
  • 如果不知道类名,可以使用File获取目录内容:File d = new File(&lt;knowDirectroy&gt;); File[] f = d.listFiles();。当然,目录中应该只有一个.class 文件。否则,您没有任何更改来加载正确的类(或者您有更多信息吗?)
  • 非常感谢,我的问题解决了。

标签: java reflection classloader


【解决方案1】:

cmets总结给出最终答案:

1:如果不知道类名,可以使用File获取目录的内容:

File d = new File("<knowDirectory>");
File[] f = d.listFiles();

当然,目录中应该只有一个.class文件。

2.: 这样你就知道类文件的名称和路径了。加载它

Class c = Class.forName("<classname>").

你也可以通过反射获得所有可用的方法:

Methods[] m = c.getMethods();

3(A).:如果不知道要调用的方法的名称,只知道它的签名(即返回类型和参数),可以使用m.getReturnType()m.getParameterTypes() 查找具有指定签名的方法。如果有多个,则无法区分它们。如果只有一个带有签名的方法,只需使用它(通过反射调用)。像这样的东西(对于返回类型Double 和单个参数String):

Class<?>[] params = m.getParameterTypes();
Class<?> r = m.getReturnType();
if(r.getName().equals(Double.class.getName())
   && params.length == 1
   && params[0].getName().equals(String.class.getName()))
{
   // invoke
}

3(B).:如果你强制用户实现一个抽象类(或接口),因此,你知道要实现的方法的名称,加载类并转换它到界面:

Class childClass = Class.forName("DerivedClassName");
MyAbstractClass userOperator = (MyAbstractClass)childClass.newInstance();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2011-01-06
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 2017-11-24
    相关资源
    最近更新 更多