在研究Unsafe类的时候发现了一段有趣的代码,如下:
public static Unsafe getUnsafe() {
Class cc = sun.reflect.Reflection.getCallerClass(2); // 获取调用栈信息
if (cc.getClassLoader() != null)
throw new SecurityException("Unsafe");
return theUnsafe;
}
深入看了下,原来这段代码的目的是为了对Unsafe的安全使用做控制,不允许其他类直接调用Unsafe的静态方法getUnsafe():(直接调用会抛异常)
Class cc = sun.reflect.Reflection.getCallerClass(2);
这段代码是获取类的调用栈信息,参数i(int 类型)表示栈帧的层次,比如i=0返回Reflection类本身,i=1则返回调用Refelection的类Unsafe,i=2则返回调用Unsafe类的类,这样就可以判断Unsafe是否是直接被调用的。不过我们可以绕过这个限制,使用Java的反射调用完成:
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
这样就可以使用Unsafe了。
下面是Refection类的源码:
/*
* %W% %E%
*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/** Common utility routines used by both java.lang and
java.lang.reflect */
public class Reflection {
/** Used to filter out fields from certain classes from public
view, where those fields may contain VM-internal objects */
private static Map/*<Class, String[]>*/ fieldFilterMap = Collections.synchronizedMap(new HashMap());
/** Returns the class of the method <code>realFramesToSkip</code>
frames up the stack (zero-based), ignoring frames associated
with java.lang.reflect.Method.invoke() and its implementation.
The first frame is that associated with this method, so
<code>getCa