检查类是否存在而不进入ClassNotFoundException

时间:2013-11-06 10:30:07

标签: java

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

到目前为止,我有两个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 个答案:

答案 0 :(得分:5)

我坚持使用Class.forName方法。

您可以将类和包名称存储在CollectionSet中,并循环显示这些元素。获得ClassNotFoundException后,您就可以继续搜索了。如果没有异常,则使用break退出循环,因为找到了您要查找的类。

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

它基本上解除了您在整个CLASSPATH中挖掘并查找要加载到VM中的类文件以及处理诸如VM是否已加载类等问题的麻烦。 / p>

修改

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

Here是一篇关于Java类加载器的好文章,因为如果你仍然决定不使用Class.forName

答案 1 :(得分: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;
}

答案 2 :(得分:4)

您可以使用Guava's Reflection实用程序来获取类路径中加载的每个类的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加载类。

答案 3 :(得分: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;
}