【问题标题】:Java - Iterate + Instantiate Directory of ClassesJava - 迭代 + 实例化类目录
【发布时间】:2020-11-25 05:15:09
【问题描述】:

我有一个名为Intent 的Java 类。在名为intents 的目录中,我定义了Intent 的几个子类。现在,在我的 runner 类中,我想将每个子类实例化为一个数组列表,如下所示:

public static String parseTranscript(String transcript) {
    ArrayList<Intent> intents = new ArrayList<Intent>();

    File[] intentFiles = new File("./intents").listFiles();
        for (File fileName : intentFiles) {
          //for each of the intents defined in "intents/", 
          //create a new class and add to the array list.

          //intents.add(new fileName.ObjectName()); 
        }
  }

所以,如果我理解正确,我需要打开目录,获取所有文件名,然后从该文件名创建一个对象。最好的方法是什么?

文件结构:

- Intent.java
- Main.java
- intents/
    - HelloIntent.java
    - GameIntent.java
    .
    .
    .

目标是做到这一点不必在运行器中手动定义每个子类。

【问题讨论】:

  • 这取决于您运行的环境。最常见的情况是作为基准,我建议查看SPI

标签: java file class object dynamic


【解决方案1】:

你可以这样试试。使用Class.forName,然后检查getSuperclass 是否返回Intent

ArrayList<Intent> intents = new ArrayList<Intent>();
String pathName = "./intents";
File[] intentFiles = new File(pathName).listFiles();
for (File fileName : intentFiles) {
    if (fileName.isFile() && fileName.getName().endsWith(".class")) {
        String className = packageName + '.' + fileName.getName().substring(0, fileName.getName().length() - 6);
        Class<?> aClass = Class.forName(className);
        if (aClass.getSuperclass().equals(Intent.class)) {
            Constructor<?> firstConstructor = aClass.getConstructors()[0];
            Intent o = (Intent) firstConstructor.newInstance(null);
            intents.add(o);
        }
    }
}

以这种方式获取pathName 会更好:

String pathName = Thread.currentThread().getContextClassLoader()
        .getResources("intents").nextElement().getFile();

获得正确的构造函数可能需要改变:

Constructor<?> firstConstructor = aClass.getConstructors()[0];

【讨论】:

    猜你喜欢
    • 2020-10-26
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 2022-10-18
    相关资源
    最近更新 更多