检查类是否存在而不进入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; }