为了安排作业的执行,我得到一个类的名称作为字符串输入 这个类可能是两个包中的一个,但我不知道哪一个,所以我必须检查这个。
到目前为止,我有两个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
的情况下重写它?
答案 0 :(得分:5)
我坚持使用Class.forName
方法。
您可以将类和包名称存储在Collection
或Set
中,并循环显示这些元素。获得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;
}