在静态方法URL.setURLStreamHandlerFactory的Java文档中,有一条警告"在给定的Java虚拟机中最多可以调用一次此方法".
我简要地看了一下源代码,在URL类中有一个静态实例变量:
static URLStreamHandlerFactory factory;
Run Code Online (Sandbox Code Playgroud)
和setURLStreamHandlerFactory只是将工厂分配给这个变量:
public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) {
synchronized (streamHandlerLock) {
if (factory != null) {
throw new Error("factory already defined");
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSetFactory();
}
handlers.clear();
factory = fac;
}
}
Run Code Online (Sandbox Code Playgroud)
允许多次调用此方法将导致覆盖此工厂实例变量,但我不明白为什么Java会想要阻止此行为.
为什么Java要求每个JVM只能调用一次此方法?
似乎没有确切的理由.
有趣的是,Eclipse"Runnable JAR File Exporter"功能注册了一个自定义URLStreamHandlerFactory命名RsrcURLStreamHandlerFactory.
URLStreamHandlerFactory本身包装另一个URLStreamHandlerFactory并提供setURLStreamHandlerFactory覆盖它的方法.引用该方法的文档:
允许添加另一个URLStreamHandler.URL.setURLStreamHandlerFactory不允许添加多个工厂.除了"rsrc"之外,所有其他协议都会调用链式工厂.使用null清除以前设置的Handler.
这setURLStreamHandlerFactory可以被多次调用,并且应该提供一些证据,证明更改处理程序不应该导致任何奇怪的行为.
更有趣的是,我发现1998年JDK 功能请求的事实setURLStreamHandlerFactory应该允许多次调用,以便可以将多个处理程序链接在一起.功能请求已解决为Future Project,但显然从未实现过.