Java Magic. Part 1: java.net.URL
Java Magic. Part 1: java.net.URL
@(Base)[JDK, url, magic, 黑魔法]
英文原文
转载请写明:原文地址
系列文章:
-Java Magic. Part 1: java.net.URL
-Java Magic. Part 2: 0xCAFEBABE
-Java Magic. Part 3: Finally
-Java Magic. Part 4: sun.misc.Unsafe
废话不多说,首先我们看如下代码:
HashSet set = new HashSet();
set.add(new URL("http://google.com"));
set.contains(new URL("http://google.com"));
Thread.sleep(60000);
set.contains(new URL("http://google.com"));
代码的第3行和第5行分别会输出什么呢?
当然不会是true, 如果是true的话,这篇文章也就不会有java黑魔法的后缀了。简单地说吧,当你有运行的PC有网络链接的时候,返回结果是false
。如果你关掉你的网络链接,比如wi-if,那么该段程序的返回值就是true
。
这么奇葩的直接原因就是URL
类的hashCode()
和equals()
方法的实现。
下面是hashCode()
方法:
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
值得注意的是,URL是一个immutable的对象。
我们可以显然看到这个URL的hashCode值是一个私有域。也就是说,只会计算一次。什么是代码中提到的handler呢?它其实是URLStreamHandler
的子类,具体的类型和当前的网络协议类型(file,http,ftp)有着密不可分的关系。我们可以看看URL.hashCode()
方法上面的注释:
The hash code is based upon all the URL components relevant for URL comparison. As such, this operation is a blocking operation.
翻译过来就是:hash code的计算和URL的所有相关属性都有关系。例如,这个操作是不是blocking的。
WTF,BLOCKING OPERATION?!
好了这个事情我们暂时放一边。另外这个hashCode的计算奇葩的地方在于,这个handler竟然会解析ip地址参与计算。我们拿这个google.com
为例子。当host的ip是动态的时候,或者说有一个域名解析的负载均衡的时候,这个hashCode()
方法就会针对google.com
计算出两个完全不同的hashCode值。
其实最让人无法接受的是URLStreamHandler
会开启一个URLConnection
,当然这又是另外一个话题啦。
How to avoid this?
- 用
java.net.URI
来替换java.net.URL
。虽然这不算是个非常好的办法,但至少有一个靠谱hashCode。 - 千万不要在
collections
中使用java.net.URL
。一个好的选择是,在collections
中放string对象来表示hostname,然后当需要的时候再使用URL对象。 - 关闭你的网络连接,当计算的hashCode值的时候。虽然只是个玩笑,但是确实很有帮助
最新文章
- [转]nopCommerce Widgets and How to Create One
- 神奇的BFC以及被忽略的东西
- IL指令详细
- Makefile中头文件在依赖关系中作用
- mysql 查询当天、本周,本月,上一个月的数据
- 01.Sencha ExtJS 6 - Generate Workspace and Application
- CSS浮动(float,clear)通俗讲解
- 把 Notepad++ 打造成一款易用的C#脚本编辑器
- Office——EXCEL 打开自动修改 关闭自动保存
- Runner站立会议01
- struts2 <;s:property/>;标签的使用--输出时间格式转换
- Create Entity Data Model
- Android沉浸式状态栏实现
- SQL Server常用脚本
- EasyUI初体验--右键弹框
- shell命令一行代码搞定【转】
- conn.go 源码阅读
- [NewLife.XCode]高级查询(化繁为简、分页提升性能)
- vue-router进阶-3-过渡动效
- SAP 官网中文帮助文件&;BP中文资料汇总
热门文章