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值的时候。虽然只是个玩笑,但是确实很有帮助
Java Magic. Part 1: java.net.URL的更多相关文章
- Magic Cast Method in Java Magic Trick In Java
https://www.atlassian.com/blog/archives/magic_trick_in_java https://www.gamlor.info/wordpress/2010/1 ...
- Java Magic. Part 4: sun.misc.Unsafe
Java Magic. Part 4: sun.misc.Unsafe @(Base)[JDK, Unsafe, magic, 黑魔法] 转载请写明:原文地址 系列文章: -Java Magic. P ...
- Java Magic. Part 3: Finally
Java Magic. Part 3: Finally @(Base)[JDK, magic, 黑魔法] 转载请写明:原文地址 英文原文 系列文章: -Java Magic. Part 1: java ...
- Java Magic. Part 2: 0xCAFEBABE
Java Magic. Part 2: 0xCAFEBABE @(Base)[JDK, magic, 黑魔法] 转载请写明:原文地址 英文原文 系列文章: -Java Magic. Part 1: j ...
- Java魔法堂:URI、URL(含URL Protocol Handler)和URN
一.前言 过去一直搞不清什么是URI什么是URL,现在是时候好好弄清楚它们了!本文作为学习笔记,以便日后查询,若有纰漏请大家指正! 二.从URI说起 1. 概念 URI(Uniform Reso ...
- java.net.MalformedURLException: Illegal character in URL
在进行接口测试时,意外发现返回结果报java.net.MalformedURLException: Illegal character in URL,意思是“在URL中的非法字符”,我的参数是经过ba ...
- java基础:网络编程TCP,URL
获取域名的两种方法: package com.lanqiao.java.test; import java.net.InetAddress;import java.net.UnknownHostExc ...
- Preferred Java way to ping a HTTP Url for availability
I need a monitor class that regularly checks whether a given HTTP URL is available. I can take care ...
- URL中增加BASE64加密的字符串引起的问题(java.net.MalformedURLException:Illegal character in URL)
序 昨天在做一个 Demo 的时候,因为是调用第三方的接口,採用的是 HTTP 的通信协议,依照文档上的说明,须要把參数进行加密后增加到 URL 中.可是,就是这个看似普普通通的操作,却让我着实费了非 ...
随机推荐
- php单例模式实现对象只被创建一次 mysql单例操作类
这是我在php面试题中遇到的一道试题,单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,不需要每次都去new了,这样极大的降低了资源的耗费. ...
- 既做无线客户端又做无线ap、又可只存在一种模式
1. 1.1 打开 /barrier_breaker/package/base-files/files/etc/init.d 加入 disable_sta_mode_wifi_interfaces # ...
- Robots.txt 编写
搜索引擎Robots协议,是放置在网站根目录下robots.txt文本文件,在文件中可以设定搜索引擎蜘蛛爬行规则.设置搜索引擎蜘蛛Spider抓取内容规则.下面Seoer惜缘举例robots写法规则与 ...
- js 正则用空格分割字符串
var filename = "ASDFK*SADF+ALDLAS-LDKFADFa*seAc tion.java";var arr = filename.split(/\*|\- ...
- Android应用程序如何调用shell脚本(一)
转自: Android应用程序如何调用shell脚本(一) 一般来说, Android 下的应用程序可以“直接”得到的最大的权限为 system ,但是如果我们需要在程序中执行某些需要 root 权限 ...
- EF webapi json序列化 表间相互引用 无限循环问题解决方案
WebApiConfig.cs中加入 如下代码即可解决无限循环问题 var json = config.Formatters.JsonFormatter; // 解决json序列化时的循环引用问题 j ...
- 从Exchager数据交换到基于trade-off的系统设计
可以使用JDK提供的Exchager类进行同步交换:进行数据交换的双方将互相等待对方,直到双方的数据都准备完毕,才进行交换.Exchager类很少用到,但理解数据交换的时机却十分重要,这是一个基于tr ...
- 杂项:flex (adobe flex)
ylbtech-杂项:Flex (Adobe Flex) Flex指Adobe Flex,基于其专有的Macromedia Flash平台,它是涵盖了支持RIA(Rich Internet Appli ...
- 在WINDOWS任务计划程序下执行PHP文件 PHP定时功能的实现
最近需要做一个定时任务功能,从网站找了很多相关的代码,windows实现方法综合起来大概就两种, 一.使用PHP ignore_user_abort 函数 即使关掉浏览器也能正常运行:(个人感觉PHP ...
- uploadify是通过flash上传,服务器获取type为application/octet-stream
uploadify是通过flash上传,服务器获取type为application/octet-stream,因此允许上传的类型要加上application/octet-stream
- Magic Cast Method in Java Magic Trick In Java