3.6. 在部署中使用类加载器编程
3.6.1. 在部署中以编程方式载入类和资源
您可以以编程方式查找或加载应用程序代码中的类和资源。您选择的方法取决于多个因素。本节介绍可用的方法,并提供了有关何时使用它们的指导。
使用 Class.forName()方法加载类
您可以使用 Class.forName()
方法以编程方式加载和初始化类。这个方法有两个签名:
class.forName(String className)
:此签名仅取一个参数,即您需要加载的类的名称。通过此方法签名,当前类的类加载程序将加载类并默认初始化新加载的类。
class.forName(String className, boolean initial, ClassLoader loader loader)
:此签名需要三个参数:类名称、布尔值,指定是否初始化类,以及加载该类的
ClassLoader
。
建议使用三个参数签名来以编程方式加载类。通过此签名,您可以控制您是否希望在加载时初始化目标类。获取和提供类加载器也更高效,因为 JVM 不需要检查调用堆栈来确定要使用的类加载程序。假设包含代码的类名为 CurrentClass
,您可以使用 CurrentClass .class.getClassLoader()
方法获取类 loader。
以下示例提供了类加载程序来加载并初始化 TargetClass
类:
Class<?> targetClass = Class.forName("com.myorg.util.TargetClass", true, CurrentClass.class.getClassLoader());
使用给定名称查找所有资源
如果您知道资源的名称和路径,直接加载资源的最佳方法是使用标准 Java 开发套件(JDK) 类或 Class
Loader
API。
加载单个资源。
若要加载位于与部署中的类或其他类相同的目录中的单个资源,您可以使用
Class.getResourceAsStream()
方法。InputStream inputStream = CurrentClass.class.getResourceAsStream("targetResourceName");
加载单个资源的所有实例。
要加载对您部署的类 loader 可见的单个资源的所有实例,请使用
Class.getClassLoader().getResources(String resourceName)
方法,其中resourceName
是资源的完全限定路径。此方法为类加载器使用给定名称访问的资源返回所有URL
对象的枚举。然后,您可以使用openStream()
方法迭代 URL 数组以打开各个流。下例加载资源的所有实例,并迭代结果。
Enumeration<URL> urls = CurrentClass.class.getClassLoader().getResources("full/path/to/resource"); while (urls.hasMoreElements()) { URL url = urls.nextElement(); InputStream inputStream = null; try { inputStream = url.openStream(); // Process the inputStream ... } catch(IOException ioException) { // Handle the error } finally { if (inputStream != null) { try { inputStream.close(); } catch (Exception e) { // ignore } } } }
注意由于 URL 实例是从本地存储加载的,因此不需要使用
openConnection()
或其他相关方法。流更易于使用并最小化代码的复杂性。从类加载器加载类文件。
如果已经载入了一个类,您可以使用以下语法载入与该类对应的类文件:
InputStream inputStream = CurrentClass.class.getResourceAsStream(TargetClass.class.getSimpleName() + ".class");
如果还没有载入该类,则必须使用类加载器并转换路径:
String className = "com.myorg.util.TargetClass" InputStream inputStream = CurrentClass.class.getClassLoader().getResourceAsStream(className.replace('.', '/') + ".class");