【问题标题】:Load all classes in a specific folder without knowing package name - java在不知道包名的情况下加载特定文件夹中的所有类 - java
【发布时间】:2015-07-20 20:42:03
【问题描述】:

我有一个代码可以加载文件夹中具有相同包名 (second) 的所有类。

如何更改它以将所有类加载到带有 deference 包的文件夹中(不在 second 中)(我们不知道包名称)

int classCounter = 0;

File folderAdded = new File("..//940424//second");
File [] classFileAdded = folderAdded.listFiles();
String [] addedClassName = new String [classFileAdded.length];
List<Operations> newOp = new ArrayList<Operations>();
Operations newOpTemp = null;

for(int i = 0; classCounter < classFileAdded.length; classCounter++){
    addedClassName [classCounter] = classFileAdded[classCounter].getAbsolutePath().substring(classFileAdded[classCounter].getAbsolutePath().lastIndexOf("\\")+1); 
    addedClassName [classCounter] = addedClassName[classCounter].substring(0,(addedClassName[classCounter].lastIndexOf(".")));
    addedClassName [classCounter] = "second." + addedClassName[classCounter];

    Class addedClass = Class.forName(addedClassName[classCounter]);
    newOpTemp = (Operations)addedClass.newInstance();
        if (newOpTemp instanceof Operations){
            newOp.add( i, newOpTemp);
            i++;
    }

【问题讨论】:

  • 你不需要知道包,只需要给出父文件夹,然后你可以递归地遍历文件夹并过滤所有文件名包含java的文件。所以你会得到所有的文件
  • 我试过了,当我们在不同的包中有一些类(不是second)时,在运行时发生异常(NoClassDefFoundError: second/ClassInThirdPackage(wrong name: third/ClassInThirdPackage))!

标签: java reflection classloader


【解决方案1】:

我想到了两件事:

  1. 如果你想加载类,对应的文件夹必须在你的类路径中(你能确保这一点 -- 因为你不知道文件夹的名字吗?)
  2. 如果要加载带有包a.b.ClassName 的类,文件必须位于文件夹a/b/ClassName.class 中(否则加载将失败)

更新

如果您知道文件夹名称,那么您也知道包名称(这就是诀窍)。它必须在Java中相互对应。如果一个类在包a.b 中,它必须在文件夹a/b/ 中。如果您只知道根文件夹,即pathToRootFolder/a/b/,您可以使用

File root = new File("<rootFolder>");
File[] files = root.listFiles()

并检查每个文件是否为目录:

for(File f : files) {
  if(f.isDirectory()) {
    // do processing
  }
}

如果单个包结构中只有一个文件,应该只有一个目录,名称​​必须对应包名(当然需要“步入目录”直到没有进一步的嵌套,即没有子文件夹,最后一个文件夹包含您要加载的实际类。这种方式可以提取目录结构,从而提取包名。

结束更新

关于您的代码的一些附带说明:

  1. 为什么new File("..//940424//second") 中的//(这是错字吗,应该是\\)[顺便说一句:最好使用File.separator]
  2. 为什么你的 for 循环中有变量 i 但实际上使用 classCounter ??
  3. addedClassName[classCounter] = classFileAdded[classCounter].getAbsolutePath().substring(classFileAdded[classCounter].getAbsolutePath().lastIndexOf("\\")+1); 中提取文件名,对吗?为什么不直接使用addedClassName[classCounter] = classFileAdded[classCounter].getName()

【讨论】:

  • 问题不是文件夹名称!我们知道文件夹名称,但我们不知道包名称!此代码的用户可能会在不同的包中编写他的类,并将它们放在一个文件夹中,我告诉他它的路径!我想知道有没有办法加载独立于包名的类?关于备注:首先感谢您的建议,No.1和No.3您说的对。谢谢你。 No.2 我决定检查加载的类是否是我的接口的实例。如果是,我需要持有它们,否则不需要持有它们。
【解决方案2】:

你可以试试这个:

Reflections reflections = new Reflections("mysh.im.monitor");
reflections.getSubTypesOf(Monitor.class);

在此之前,请确保您的文件夹位于类路径中。

maven 依赖

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.9</version>
</dependency>

【讨论】:

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