共享一些最近工作中收集到的一些java小代码,不知道如何归档好,记录到这持续更新吧。
(1)通过接口sun.reflect.Reflection.getCallerClass()可以得到运行时线程栈调用本函数的类,是不是很神奇!这样可以不用通过函数参数标识来区分函数该执行哪个分支的逻辑了,当然还可以实现其他很特别的功能(不过,除特殊需求时没办法,否则JDK是不推荐使用这类接口的)。
(2)ConcurrentHashMap.putIfAbsent用法实例,用Map实现缓存时常会用到。你是这样用的么?
Object newLock = new Object();
lock = parallelLockMap.putIfAbsent(className, newLock);
if (lock == null) {
lock = newLock;
}
操作lock其他逻辑……
(3)这样代码可得到系统类加载器:
java.lang.ClassLoader.getSystemClassLoader()
(4)正无穷大的Double还可以这样表示: 1.0 / 0.0
(5)hashCode和equals方法重写可参考:java.lang.StackTraceElement
(6)StringBuilder和StringBuffer都继承同一个抽象类AbstractStringBuilder,默认都初始化长度为16的char数组拼接存储字符串字符信息,区别是StringBuffer通过synchronized每个方法实现了同步。注意字符串append过长时根据场景设置下初始化长度,避免char数组不停的扩展拷贝。
(7)接口里不能有具体的方法实现代码对么?那请看看下面这个强大的接口神器:
public interface CookiePolicy {
public static final CookiePolicy ACCEPT_ALL = new CookiePolicy(){
public boolean shouldAccept(URI uri, HttpCookiecookie) {
return true;
}
};
public static final CookiePolicy ACCEPT_NONE = newCookiePolicy(){
public boolean shouldAccept(URI uri, HttpCookiecookie) {
return false;
}
};
public static final CookiePolicy ACCEPT_ORIGINAL_SERVER = new CookiePolicy(){
public boolean shouldAccept(URI uri, HttpCookiecookie) {
return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost());
}
};
public boolean shouldAccept(URI uri, HttpCookie cookie);
}
(8)192.168.11.11在Java里您如何存储?字符串么?起始用一个int就够了:
// byte[4] 转换int
int address = addr[3] & 0xFF;
address |= ((addr[2] << 8) & 0xFF00);
address |= ((addr[1] << 16) & 0xFF0000);
address |= ((addr[0] << 24) & 0xFF000000);
// int 转换byte[4]
addr[0] = (byte) ((address >>> 24) & 0xFF);
addr[1] = (byte) ((address >>> 16) & 0xFF);
addr[2] = (byte) ((address >>> 8) & 0xFF);
addr[3] = (byte) (address & 0xFF);
(9)如何将字符串"java.lang.String"转换为"java/lang/String.class"?
这样就错了,会按正则表达式解析出格式非法的:
String result = name.replaceAll(".", "/");
这样就对了,但效率不行,咋替换个字符这么麻烦:
String result = name.replaceAll("\\.", "/");
这样就又快又清晰了:
String result = name.replace('.' ,'/');
(10)为啥ConcurrentHashMap能实现分段加锁,因为它的每段是这样定义的,每段都能单独加锁释放锁。
static final class Segment<K,V> extends ReentrantLock{...}
(11)想自己实现个简单的分段加锁咋办?把锁对象放到ConcurrentHashMap里就行了:
private final ConcurrentHashMap<String, Object> parallelLockMap;
(12)HashSet相当取巧,就是用HashMap的功能包装一下得到的,内部定义了"private transient HashMap map;",相关接口也都是在操作这个map,其中key是真实要存储的值,value对应的对象都是相同的: private static final Object PRESENT = new Object();
(13)LinkedHashMap构造时有个神奇的accessOrder参数,默认false代表按插入顺序排序,即我们最常使用的有序map。可当设置为true时:该哈希映射的迭代顺序就是最后访问其条目的顺序,从近期访问最少到近期访问最多的顺序(访问顺序),最近访问即最近调用get(key)的条目。