编辑:事实证明这个问题被错误地问了 - 请参阅my answer below。请投票关闭它。
对于单元测试,我需要让new java.net.URL(String)
构造函数抛出MalformedURLException
,但它需要花费很长时间才能完成 - 2.5秒。
我理解这可能与尝试创建协议处理程序有关,因此我尝试不指定协议处理程序,例如:
new URL(null);
new URL("://");
new URL("/abc");
我简要介绍了实现,似乎是在预先准备URL字符串以消除明显的错误。为什么需要这么长时间,即使是“null”?
答案 0 :(得分:3)
因为URL类的长度相当长,并尝试了几种不同的尝试来解析给定(非法)的Url。它甚至尝试加载使用Urls内容解析的不同系统包。
确切的程序在URL constructor的Javadoc中列出。
由于这些操作涉及访问和加载不同的类和文件,因此首次访问此类非法Url可能需要相当长的时间。
答案 1 :(得分:1)
也许您可以使用URI来提高性能?
注意,URI类确实执行其组件字段的转义 某些情况下。管理编码和推荐的方法 URL的解码是使用URI,并在这两者之间进行转换 使用toURI()和URI.toURL()的类。
也可以使用URLEncoder和URLDecoder类,但仅限于 HTML表单编码,与编码方案不同 在RFC2396中定义。
来自http://java.sun.com/j2se/1.5.0/docs/api/java/net/URL.html
“鼓励人们使用URI进行解析和URI比较,以及 保留用于访问URI本身的URL类,获取协议 处理程序,与协议等交互。所以,目前,我们没有 计划更改URL.equals / hashCode行为,我们将离开 当我们重新调查我们的选择时,这个错误一直持续到Tiger。“
来自http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4434494,2001。
答案 2 :(得分:1)
这可能是导致延迟的其他原因吗?我不能重现这个:
public class UrlTest {
static public void urltest(String s) {
long start = System.currentTimeMillis();
try {
new URL(s);
System.out.println("successfully created URL after "+(System.currentTimeMillis()-start)+" milliseconds. URL: "+s);
} catch(Exception e) {
System.out.println(e.toString()+" after "+(System.currentTimeMillis()-start)+" milliseconds. URL: "+s);
}
}
static public void main(String[] args) {
System.out.println(System.getProperty("java.version"));
urltest(null);
urltest("://");
urltest("/abc");
}
}
输出:
1.6.0_18-ea
java.net.MalformedURLException after 0 milliseconds. URL: null
java.net.MalformedURLException: no protocol: :// after 1 milliseconds. URL: ://
java.net.MalformedURLException: no protocol: /abc after 0 milliseconds. URL: /abc
关于equals()
,这来自javadoc:
如果两个主机名都可以解析为相同的IP地址,则认为两台主机是等效的。否则,如果无法解析任何一个主机名,则主机名必须相等而不考虑大小写;或两个主机名都等于null。
由于主机比较需要名称解析,因此此操作是阻止操作。
注意:已知已定义的equals行为与HTTP中的虚拟主机不一致。
答案 3 :(得分:1)
感谢您分享您的单元测试结果 - 您说得对,URL创建几乎没有。比较导致麻烦:
Assert.assertThat(url, equalTo(new URL("http://aa"))); // about 2 seconds
似乎真的打电话给http://aa
!似乎只有“localhost”它很快:
Assert.assertThat(url, equalTo(new URL("http://localhost"))); // a few ms
解决方案是比较字符串表示:
Assert.assertThat(url.toExternalForm(), equalTo(new URL("http://aa").toExternalForm()));
答案 4 :(得分:0)
单步执行它,看看它花费的时间!
我预计它会尝试进行DNS查找,并且您的DNS客户端或服务器配置错误。