Java – 遍历并实例化类目录

huangapple go评论74阅读模式
英文:

Java - Iterate + Instantiate Directory of Classes

问题

我有一个名为Intent的Java类。在一个名为intents的目录中,我定义了几个Intent的子类。现在,在我的运行器类中,我想要实例化每个子类,并将它们放入一个数组列表中,如下所示:

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

    File[] intentFiles = new File("./intents").listFiles();
    for (File fileName : intentFiles) {
        // 对于在"intents/"中定义的每个Intent,
        // 创建一个新的类并添加到数组列表中。

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

所以,如果我理解正确,我需要打开目录,获取所有文件名,然后根据文件名创建一个对象。怎样是最佳的做法?

文件结构:

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

目标是在运行器中不必手动定义每个子类。

英文:

I have a Java class called Intent. In a directory called intents, I have defined several child classes of Intent. Now, in my runner class, I would like to instantiate each of the child classes into an array list as such:

public static String parseTranscript(String transcript) {
    ArrayList&lt;Intent&gt; intents = new ArrayList&lt;Intent&gt;();

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

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

So, if I understand correctly, I would need to open the directory, get all file names, then create an object from that file name. What is the best way to do this?

File structure:

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

The goal is to do this without having to manually define each child class in the runner.

答案1

得分: 2

你可以尝试这样做。使用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];
英文:

You can try in this way. With Class.forName and then checking if getSuperclass returns Intent

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

Getting pathName would be better do in this way:

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

Getting right constructor maybe need change in this:

Constructor&lt;?&gt; firstConstructor = aClass.getConstructors()[0];

huangapple
  • 本文由 发表于 2020年8月5日 11:58:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63258216.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定