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

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

到现在为止,我有两个try-catch-blocks

Class clazz; String className; //the above mentioned string, will be initialized try { clazz = (Class) Class.forName("package.one." + className); } catch (ClassNotFoundException ex) { try { clazz = (Class) Class.forName("package.two." + className); } catch (ClassNotFoundException ex1) { //some error handling code here, as the class is //in neither of the two packages } } 

对于更多的包,这将变得更加丑陋,更难以理解。 此外,对我而言,它违反了例外的概念,因为exception不应该被预期/用于流量控制!
有没有办法在不使用ClassNotFoundException情况下重写它?

我坚持使用Class.forName方法。

您可以将类和包名称存储在Collection s或Set并循环遍历这些元素。 当您收到ClassNotFoundException ,您只需继续搜索。 如果没有exception,则使用break退出循环,因为您找到了要查找的类。

我之所以选择Class.forName是因为如果它还没有被VM加载,它会为你加载类。 这是一个非常强大的副作用。

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

编辑:

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

如果您仍然决定不使用Class.forName ,那么这篇关于Java类加载器的文章很好。

 public Class getClass(String className) { String packages[] = { "package.one.", "package.two." }; for (int j = 0; j < packages.length; j++) { try { return (Class) Class.forName(packages[j] + className); } catch (ClassNotFoundException ex) { System.out.println("Package "+packages[j]+" is not worked"); } } return null; } 

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

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

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

在这种情况下,我不担心使用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; }