7

为了安排作业的执行,我将类的名称作为字符串输入。
这个类可能在两个包之一中,但我不知道是哪一个,所以我必须检查这个。

到目前为止,我有两个 try-catch-blocks

Class<Job> clazz;
String className; //the above mentioned string, will be initialized

try {
    clazz = (Class<Job>) Class.forName("package.one." + className);
} catch (ClassNotFoundException ex) {
    try {
        clazz = (Class<Job>) Class.forName("package.two." + className);
    } catch (ClassNotFoundException ex1) {
      //some error handling code here, as the class is
      //in neither of the two packages
    }
}

对于更多的包,这将变得更加丑陋和不可读。此外,对我来说,它反对异常的概念,因为不应该期望/使用异常来进行流量控制!
有没有办法在不使用的情况下重写它ClassNotFoundException

4

4 回答 4

5

我会坚持这种Class.forName方法。

您可以将类和包名称存储在Collections 或Sets 中,并遍历这些元素。当你得到一个ClassNotFoundException,你就继续你的搜索。如果没有出现异常,则使用 退出循环break,因为您已找到要查找的类。

我选择的原因Class.forName是,如果 VM 尚未加载该类,它会为您加载该类。这是一个非常强大的副作用。

它基本上免除了您在整个过程中挖掘CLASSPATH并寻找要加载到VM中的类文件以及处理诸如该类是否已经被VM加载等问题的麻烦。

编辑:

Jakob Jenkov 写了一些关于 Java 的非常棒的文章/教程。我发现它们在处理反射、类加载器和并发(Java 的一些“最难”方面)时非常有用。

是他写的一篇关于 Java 类加载器的好文章,如果您仍然决定不使用Class.forName.

于 2013-11-06T10:36:38.010 回答
4
public Class<Job> getClass(String className) {
    String packages[] = { "package.one.", "package.two." };
    for (int j = 0; j < packages.length; j++) {
        try {
            return (Class<Job>) Class.forName(packages[j] + className);
        } catch (ClassNotFoundException ex) {
            System.out.println("Package "+packages[j]+" is not worked");
        }
    }
    return null;
}
于 2013-11-06T10:39:53.817 回答
4

您可以使用Guava 的反射实用程序来获取加载到类路径中的每个类的ClassInfo

ClassLoader classLoader = ClassLoader.getSystemClassLoader();
ClassPath classPath = ClassPath.from(classLoader);
ImmutableSet<ClassInfo> set = classPath.getTopLevelClasses();
for (ClassInfo ci : set) {
    System.out.println(ci.getName());
}

在循环中,您可以实现自定义逻辑以使用className您提供的加载类。

于 2013-11-06T11:02:35.427 回答
1

在这种情况下,我不会担心使用ClassNotFoundException. 虽然一般情况下可以不使用异常来进行流控制,但在这里它几乎不能算作这样。

我可能会将它包装在一个函数中,就像这样

public static String getPackageForClass(String className, String... packageNames) {
    for (String packageName : packageNames) {
        try {
            Class.forName(packageName + className);
            return packageName;
        } catch (ClassNotFoundException ignored) {
        }
    }
    return "";
}

或直接返回课程,如果你愿意

public static Class getPackageForClass(String className, String... packageNames) {
    for (String packageName : packageNames) {
        try {
            return Class.forName(packageName + className);
        } catch (ClassNotFoundException ignored) {
        }
    }
    return null;
}
于 2013-11-06T10:49:38.030 回答