public static final class MethodHandles.Lookup extends Object
查找类,需要创建方法处理会MethodHandles.lookup
为自己创建一个工厂。当Lookup
工厂对象创建时,查找类的身份被确定,并安全地存储在Lookup
对象。查找类(或其代表)可以使用在Lookup
对象的工厂方法来创建访问检查成员方法处理。这包括允许查找类的所有方法、构造函数和字段,甚至是私有的。
Lookup
对象对应于所有主要的用例方法,构造函数工厂方法和字段。每种方法处理工厂方法创建的是一个特定的字节码的功能等价的行为。(字节码的行为都是在java虚拟机规范。第5.4.3.5描述)这里是这些工厂方法以及由此方法处理行为之间的对应关系的总结:
lookup expression | member | bytecode behavior |
---|---|---|
lookup.findGetter(C.class,"f",FT.class) |
FT f; |
(T) this.f; |
lookup.findStaticGetter(C.class,"f",FT.class) |
static FT f; |
(T) C.f; |
lookup.findSetter(C.class,"f",FT.class) |
FT f; |
this.f = x; |
lookup.findStaticSetter(C.class,"f",FT.class) |
static FT f; |
C.f = arg; |
lookup.findVirtual(C.class,"m",MT) |
T m(A*); |
(T) this.m(arg*); |
lookup.findStatic(C.class,"m",MT) |
static T m(A*); |
(T) C.m(arg*); |
lookup.findSpecial(C.class,"m",MT,this.class) |
T m(A*); |
(T) super.m(arg*); |
lookup.findConstructor(C.class,MT) |
C(A*); |
new C(arg*); |
lookup.unreflectGetter(aField) |
(static )?FT f; |
(FT) aField.get(thisOrNull); |
lookup.unreflectSetter(aField) |
(static )?FT f; |
aField.set(thisOrNull, arg); |
lookup.unreflect(aMethod) |
(static )?T m(A*); |
(T) aMethod.invoke(thisOrNull, arg*); |
lookup.unreflectConstructor(aConstructor) |
C(A*); |
(C) aConstructor.newInstance(arg*); |
lookup.unreflect(aMethod) |
(static )?T m(A*); |
(T) aMethod.invoke(thisOrNull, arg*); |
C
是类或接口被搜索的一员,记录作为一个参数指定
refc
在查找方法。方法类型
MT
从返回类型和参数类型
T
A*
序列组成。构造函数也有一系列的参数类型和返回
A*
视为新创建的对象的类型
C
。两
MT
和字段类型
FT
记录作为一个参数指定
type
。形式参数
this
代表
C
型自参考;如果它是存在的,它总是要处理方法调用的主要论点。(在某些情况下
protected
成员,
this
可能限制类型查找类;见下文。)的名字
arg
代表所有其他方法处理参数。在示例代码为核心的反射API,名字
thisOrNull
代表空引用,如果访问的方法或字段是静态的,而
this
否则。名称
aMethod
,
aField
反射物体,并给出了相应的成员
aConstructor
站。
如果给定的成员是可变的数量(即,方法或构造函数)返回的处理方法也将variable arity。在所有其他情况下,返回的处理方法将固定数量。
讨论:等价抬头方法处理和底层的类成员和字节码的行为可以打破在几个方面:
C
不是象征性地访问从查找类的装载机,查找仍然可以成功,即使没有等效java表达式或bytecoded常数。T
或MT
不是象征性地访问从查找类的装载机,查找仍然可以成功。例如,对于MethodHandle.invokeExact
和MethodHandle.invoke
查找总会成功的,无论请求类型。CONSTANT_MethodHandle
常数的ldc
指令不受安全管理检查。Lookup
工厂方法,当一个方法创建句柄。这是从核心反射API的一个关键的区别,因为
java.lang.reflect.Method.invoke
执行访问检查对每一个来电,每一个电话。
所有的访问检查从Lookup
对象出发,比较其记录查找类对所有的请求创建的方法处理。一个Lookup
对象可以用来创建任意数量的访问检查的方法处理,所有检查单查找类。
一个Lookup
对象可以与其他受信任的代码共享,如元对象协议。一个共享的Lookup
对象代表的创造能力,在查找类的私有成员的处理方法。即使特权代码使用Lookup
对象,访问检查局限于原有的查找类的特权。
查找可能失败,因为包含类无法访问查找类,或者因为所需的类成员丢失,或者因为所需的类成员无法访问到查找类,或者因为查找对象不值得信任访问成员。在这种情况下,一个ReflectiveOperationException
将尝试查找扔。确切的类将是以下的一个:
总的来说,这一方法处理的条件下,可以抬头看了方法M
没有限制性比的条件下,查找类可以编译、验证,解决了电话M
,JVM会引发异常,像NoSuchMethodError
方法处理,查找通常会提高相应的检查异常,如NoSuchMethodException
。从查找和调用产生的方法处理效果exactly equivalent执行编译、验证,解决了电话M
。字段和构造函数的相同点是真的。
讨论:访问检查只适用于命名和反射的方法、构造函数和字段。其他方法处理的创作方法,如MethodHandle.asType
,不需要任何访问检查,并独立于任何Lookup
对象使用。
如果所需的成员protected
,通常JVM规则适用,包括查找类必须是在同一个包所需的成员的要求,或必须继承的成员。(看到java虚拟机的规范,部分4.9.2,5.4.3.5,6.4。)此外,如果所需的成员在不同的包非静态字段或方法,所得到的处理方法可能只适用于查找类或其子类的对象。这一要求是通过缩小领导this
参数的类型从C
执行(这必然是一个父类的查找类)来查找类本身。
JVM对类似的要求,invokespecial
指令,接收机参数必须匹配的解决方法和当前类。再次,这种要求是通过缩小所得到的方法句柄的主要参数的类型来实现的。(看到java虚拟机的规范,部分4.10.1.9。)
JVM是构造函数和静态初始化块具有特殊名称的内部方法("<init>"
和"<clinit>"
)。调用指令的内部语法允许他们把这样的内部方法,好像他们是正常的方法,但是JVM字节码验证器排斥。查找这样一种内在的方法将产生一个NoSuchMethodException
。
在某些情况下,之间的嵌套类的访问是由java编译器创建访问私人在相同的顶级声明另一个类的方法的一种包装方法得到的。例如,嵌套类可以访问其他相关类C.D
内如C
,C.D.E
,或C.B
私有成员,但是java编译器可能需要生成包装方法在那些相关的类。在这种情况下,对C.E
一Lookup
对象无法那些私有成员。这一限制的解决方法是Lookup.in
方法,可以将查找在C.E
成一对其他任何人的课,没有特权特殊的提升。
访问允许一个给定的查询对象可以是有限的,根据其设定的lookupModes
,以正常访问查找类成员的子集。例如,在publicLookup
方法产生一个查找对象只能访问公共类的公共成员。对方敏感的方法lookup
产生查找对象全能力相对其调用者类,模拟所有支持字节码的行为。同时,该Lookup.in
方法可能会产生一个比原来的查找对象较少的接入方式查找对象。
讨论私人访问:我们说一个查找具有私有访问如果lookup modes包括private
成员访问的可能性。在其他相关方法的记录,只有私人访问查找具有以下功能:
Class.forName
emulate invokespecial
指令delegated lookup objects
这些权限是一个事实,一个私人访问查找对象可以安全地追溯到始发班的后果,其bytecode behaviors和java语言访问权限可以可靠地确定和模拟的方法处理。
invokestatic
或
getfield
字节码指令。有一个
security manager API允许应用程序检查装载机等交叉引用。这些检查都适用
MethodHandles.Lookup
API和核心反射API(如发现
类
)。
如果安全管理器,会员查询受到额外的检查。从一到三个电话都是给安全管理器。这些要求可以通过把一个SecurityException
拒绝访问。定义smgr
作为安全经理,lookc
作为当前查找对象的查找类,refc
为包含类的成员是受到追捧,并defc
作为类的成员实际上是定义。价值lookc
定义如果当前查找对象没有private access为不存在。根据以下规则进行调用:
lookc
不存在,或者它的类装载器是不一样的refc
或祖先的类装载器,然后smgr.checkPackageAccess(refcPkg)
称,在refcPkg
是refc
包。lookc
是不存在的,然后smgr.checkPermission
与RuntimePermission("accessDeclaredMembers")
叫做。lookc
是不存在的,如果defc
和refc
是不同的,那么smgr.checkPackageAccess(defcPkg)
称,在defcPkg
是defc
包。如果请求一个来电敏感的方法处理,对bytecode behaviors一般规则,但他们把查找类账户,以特殊的方式。由此产生的方法句柄的行为就好像它是从包含在查找类中的指令调用的,所以调用方敏感的方法检测到查找类。(相比之下,这种方法处理的调用是可以忽略的。)因此,在对方敏感的方法的情况下,不同的查找类可能会产生不同的行为方法处理。
如果查找的对象是publicLookup()
,或其他一些不private access查找对象,查找类被忽略。在这种情况下,没有Caller-Sensitive方法处理可以创建,访问被禁止,并且查找失败的IllegalAccessException
。
讨论:例如,对方敏感的方法Class.forName(x)
可以返回不同类或把不同的例外,根据不同的类装载器的类来调用它。一个Class.forName
公共查询将失败,因为没有合理的方法来确定它的字节码的行为。
如果一个应用广泛共享高速缓存的方法处理,它应该使用publicLookup()
创造它们。如果有一个查找Class.forName
,它将失败,并且应用程序必须在这种情况下,采取适当的行动。它可能是一个后来的查找,也许在调用的引导方法,可以结合来电者的具体身份,使方法访问。
功能MethodHandles.lookup
外敏感,可以查找一个安全的基础。几乎所有的JSR 292 API依赖查找对象检查访问请求的其他方法。
Modifier and Type | Field and Description |
---|---|
static int |
PACKAGE
一个单一的位掩码表示
package 访问(默认),这可能有助于
lookupModes 结果。
|
static int |
PRIVATE
一个单一的位掩码表示
private 访问,这可能有助于
lookupModes 结果。
|
static int |
PROTECTED
一个单一的位掩码表示
protected 访问,这可能有助于
lookupModes 结果。
|
static int |
PUBLIC
一个单一的位掩码表示
public 访问,这可能有助于
lookupModes 结果。
|
Modifier and Type | Method and Description |
---|---|
MethodHandle |
bind(Object receiver, String name, MethodType type)
用于非静态方法的早期绑定方法句柄。
|
MethodHandle |
findConstructor(类<?> refc, MethodType type)
产生的方法处理,创建一个对象并将它初始化,使用指定类型的构造函数。
|
MethodHandle |
findGetter(类<?> refc, String name, 类<?> type)
产生一个方法来处理对一个非静态字段的读取访问。
|
MethodHandle |
findSetter(类<?> refc, String name, 类<?> type)
产生一个处理给非静态字段的写访问的方法。
|
MethodHandle |
findSpecial(类<?> refc, String name, MethodType type, 类<?> specialCaller)
为一个虚拟方法产生早期绑定的方法句柄。
|
MethodHandle |
findStatic(类<?> refc, String name, MethodType type)
用于静态方法的方法处理。
|
MethodHandle |
findStaticGetter(类<?> refc, String name, 类<?> type)
产生一个方法来处理静态字段的读取访问。
|
MethodHandle |
findStaticSetter(类<?> refc, String name, 类<?> type)
产生一个处理给静态字段的写访问的方法。
|
MethodHandle |
findVirtual(类<?> refc, String name, MethodType type)
产生一个虚拟方法的方法句柄。
|
MethodHandles.Lookup |
in(类<?> requestedLookupClass)
在指定的新查找类上创建一个查找。
|
类<?> |
lookupClass()
告诉哪个类执行查找。
|
int |
lookupModes()
告诉该查找对象可以生产的成员的访问保护类。
|
MethodHandleInfo |
revealDirect(MethodHandle target)
裂纹
direct method handle通过查找对象或类似的一个创造。
|
String |
toString()
显示的名称来查找要做。
|
MethodHandle |
unreflect(方法 m)
让
direct method handle到nullm,如果查找类许可。
|
MethodHandle |
unreflectConstructor(Constructor<?> c)
为反射的构造函数生成方法句柄。
|
MethodHandle |
unreflectGetter(Field f)
产生一个方法来处理对一个反射字段的读取访问。
|
MethodHandle |
unreflectSetter(Field f)
产生一个处理对一个反射字段的写访问的方法。
|
MethodHandle |
unreflectSpecial(方法 m, 类<?> specialCaller)
用于反射方法的方法处理。
|
public static final int PUBLIC
public static final int PRIVATE
public static final int PROTECTED
public static final int PACKAGE
public 类<?> lookupClass()
这类意味着访问权限的最高水平,但权限可以另外有限的位掩码lookupModes
,控制是否公开的成员可以访问。
public int lookupModes()
刚创建的查找对象在caller's class有所有可能的位设置,因为调用者类可以访问自己的所有成员。在一个新的查找类created from a previous lookup object查找对象可能有一些模式位设置为零。这的目的是通过新的查找对象来限制访问,以便它只能访问原始查找对象所能达到的名称,也可以访问新的查找类。
public MethodHandles.Lookup in(类<?> requestedLookupClass)
lookupClass
。
然而,由此产生的Lookup
对象确保没有更多的接入能力比原。特别是,访问能力可以丢失如下:
requestedLookupClass
-新的查找对象所需的查找类
NullPointerException
-如果参数为空
public String toString()
Class.getName
。)如果在访问允许这种查询的限制,这是通过添加一个后缀类名表示,由斜线和关键字。关键词是最大允许访问,和选择如下:
MethodHandles.lookup
。由
Lookup.in
对象总是有限制的访问,并将显示一个后缀。
(似乎奇怪的是,受保护的访问应该比私人访问更强大。独立包装的访问来看,访问是输了,因为它需要调用者和被调用者之间的直接子类关系。)
toString
方法重写,继承类
Object
in(java.lang.Class<?>)
public MethodHandle findStatic(类<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
findVirtual
或
findSpecial
。)的方法和它的所有参数类型必须要查找对象的访问。
返回的方法处理会有variable arity若方法的变量数量修改位(0x0080
)设置。
如果调用返回的方法句柄,则该方法的类将被初始化,如果它还没有被初始化。
例子:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, "asList", methodType(List.class, Object[].class)); assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
refc
-类的方法访问
name
-名称的方法
type
-方法的类型
NoSuchMethodException
如果方法不存在
IllegalAccessException
如果访问检查失败,或如果方法不
static
,或者方法的变性剂位设置和
asVarargsCollector
失败
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findVirtual(类<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
refc
)值。该方法和它的所有参数类型必须是可访问的查找对象。
当调用时,句柄将把第一个参数视为一个接收器,并在接收器的类型上发送,以确定哪些方法实现输入。(调度作用,通过invokevirtual
或invokeinterface
指令。执行相同)
第一个参数是类型refc
如果查找类具有完全的权限访问的成员。否则,成员必须protected
和第一个参数将被限制在类型查找类。
返回的方法处理会有variable arity若方法的变量数量修改位(0x0080
)设置。
因为invokevirtual
指令和方法处理产生的findVirtual
之间的一般equivalence,如果类是MethodHandle
和名称的字符串是invokeExact
或invoke
,产生的方法处理相当于一个MethodHandles.exactInvoker
或MethodHandles.invoker
同type
争论而产生。例子:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle MH_concat = publicLookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, "hashCode", methodType(int.class)); MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, "hashCode", methodType(int.class)); assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); // interface method: MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, "subSequence", methodType(CharSequence.class, int.class, int.class)); assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); // constructor "internal method" must be accessed differently: MethodType MT_newString = methodType(void.class); //()V for new String() try { assertEquals("impossible", lookup() .findVirtual(String.class, "<init>", MT_newString)); } catch (NoSuchMethodException ex) { } // OK MethodHandle MH_newString = publicLookup() .findConstructor(String.class, MT_newString); assertEquals("", (String) MH_newString.invokeExact());
refc
的类或接口的方法访问
name
-名称的方法
type
-方法的类型,与接收机参数省略
NoSuchMethodException
如果方法不存在
IllegalAccessException
如果访问检查失败,或如果方法
static
或者方法的变性剂位设置和
asVarargsCollector
失败
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findConstructor(类<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException
请求的类型必须有一个void
返回类型。(这是与JVM的处理构造函数的类型描述符。一致)
返回的方法处理会有variable arity如果构造函数的变量数量修改位(0x0080
)设置。
如果调用返回的方法句柄,则构造函数的类将被初始化,如果它还没有被初始化。
例子:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle MH_newArrayList = publicLookup().findConstructor( ArrayList.class, methodType(void.class, Collection.class)); Collection orig = Arrays.asList("x", "y"); Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); assert(orig != copy); assertEquals(orig, copy); // a variable-arity constructor: MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( ProcessBuilder.class, methodType(void.class, String[].class)); ProcessBuilder pb = (ProcessBuilder) MH_newProcessBuilder.invoke("x", "y", "z"); assertEquals("[x, y, z]", pb.command().toString());
refc
的类或接口的方法访问
type
-方法的类型,与接收机参数省略,和void返回类型
NoSuchMethodException
-如果构造函数不存在
IllegalAccessException
如果访问检查失败或如果方法的变性剂位设置和
asVarargsCollector
失败
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findSpecial(类<?> refc, String name, MethodType type, 类<?> specialCaller) throws NoSuchMethodException, IllegalAccessException
invokespecial
指令在明确指定
specialCaller
,处理方法的类型将是该方法与适当限制接收机类型前缀。(接收器类型将
specialCaller
或亚型)的方法和它的所有参数类型必须要查找对象的访问。
以前的方法解决,如果明确指定调用类是不相同的查找类,或者如果该查询对象没有private access权限,访问失败。
返回的方法处理会有variable arity若方法的变量数量修改位(0x0080
)设置。
(注:JVM内部方法命名为“ <初始化> ”是不可见的这个API,即使invokespecial指示可以参考它们在特殊情况下。使用findconstructor访问在一个安全的方式实例初始化方法。) 初始化>
例子:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... static class Listie extends ArrayList { public String toString() { return "[wee Listie]"; } static Lookup lookup() { return MethodHandles.lookup(); } } ... // no access to constructor via invokeSpecial: MethodHandle MH_newListie = Listie.lookup() .findConstructor(Listie.class, methodType(void.class)); Listie l = (Listie) MH_newListie.invokeExact(); try { assertEquals("impossible", Listie.lookup().findSpecial( Listie.class, "<init>", methodType(void.class), Listie.class)); } catch (NoSuchMethodException ex) { } // OK // access to super and self methods via invokeSpecial: MethodHandle MH_super = Listie.lookup().findSpecial( ArrayList.class, "toString" , methodType(String.class), Listie.class); MethodHandle MH_this = Listie.lookup().findSpecial( Listie.class, "toString" , methodType(String.class), Listie.class); MethodHandle MH_duper = Listie.lookup().findSpecial( Object.class, "toString" , methodType(String.class), Listie.class); assertEquals("[]", (String) MH_super.invokeExact(l)); assertEquals(""+l, (String) MH_this.invokeExact(l)); assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method try { assertEquals("inaccessible", Listie.lookup().findSpecial( String.class, "toString", methodType(String.class), Listie.class)); } catch (IllegalAccessException ex) { } // OK Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
refc
的类或接口的方法访问
name
-的方法的名称(不可“
<初始化>
”)
初始化>
type
-方法的类型,与接收机参数省略
specialCaller
-该调用的类进行
invokespecial
NoSuchMethodException
如果方法不存在
IllegalAccessException
如果访问检查失败或如果方法的变性剂位设置和
asVarargsCollector
失败
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findGetter(类<?> refc, String name, 类<?> type) throws NoSuchFieldException, IllegalAccessException
refc
的类或接口的方法访问
name
-字段的名称
type
-该字段的类型
NoSuchFieldException
如果字段不存在
IllegalAccessException
如果访问检查失败,或如果该字段是
static
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findSetter(类<?> refc, String name, 类<?> type) throws NoSuchFieldException, IllegalAccessException
refc
的类或接口的方法访问
name
-字段的名称
type
-该字段的类型
NoSuchFieldException
如果字段不存在
IllegalAccessException
如果访问检查失败,或如果该字段是
static
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findStaticGetter(类<?> refc, String name, 类<?> type) throws NoSuchFieldException, IllegalAccessException
如果调用返回的方法句柄,则该字段的类将被初始化,如果它没有被初始化。
refc
的类或接口的方法访问
name
-字段的名称
type
-该字段的类型
NoSuchFieldException
如果字段不存在
IllegalAccessException
如果访问检查失败,或如果该字段是不
static
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle findStaticSetter(类<?> refc, String name, 类<?> type) throws NoSuchFieldException, IllegalAccessException
如果调用返回的方法句柄,则该字段的类将被初始化,如果它没有被初始化。
refc
的类或接口的方法访问
name
-字段的名称
type
-该字段的类型
NoSuchFieldException
如果字段不存在
IllegalAccessException
如果访问检查失败,或如果该字段是不
static
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
defc
其中一个给定的名称和类型的方法来查找类可访问。该方法和它的所有参数类型必须是可访问的查找对象。该方法的类型的处理将是该方法,没有任何插入一个额外的接收器参数。给定的接收器将被绑定到方法处理中,因此,方法句柄的每一个调用都将在给定的接收器上调用请求的方法。
返回的方法处理会有variable arity若方法的变量数量修改位(0x0080
)是集和尾数组参数不是唯一的争论。(如果后面的数组参数是唯一的参数,给定的接收器值将被绑定到它。)
这相当于下面的代码:
哪里import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle mh0 = lookup().findVirtual(defc, name, type); MethodHandle mh1 = mh0.bindTo(receiver); MethodType mt1 = mh1.type(); if (mh0.isVarargsCollector()) mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1)); return mh1;
defc
是
receiver.getClass()
或超类型,类,其中请求的方法是查找类可访问。(注意,
bindTo
不保留变量的情况。)
receiver
-对象的方法访问
name
-名称的方法
type
-方法的类型,与接收机参数省略
NoSuchMethodException
如果方法不存在
IllegalAccessException
如果访问检查失败或如果方法的变性剂位设置和
asVarargsCollector
失败
SecurityException
-如果一个安全管理是目前这
refuses access
NullPointerException
-如果任一参数为空
MethodHandle.bindTo(java.lang.Object)
,
findVirtual(java.lang.Class<?>, java.lang.String, java.lang.invoke.MethodType)
public MethodHandle unreflect(方法 m) throws IllegalAccessException
accessible
标志,访问检查立即执行,对查课代表。如果nullm不公开,不与不受信任的各方分享由此产生的处理。
返回的方法处理会有variable arity若方法的变量数量修改位(0x0080
)设置。
如果nullm是静态的,如果返回的处理方法被调用时,该方法的类将被初始化,如果它还没有被初始化。
m
-反射法
IllegalAccessException
如果访问检查失败或如果方法的变性剂位设置和
asVarargsCollector
失败
NullPointerException
-如果参数为空
public MethodHandle unreflectSpecial(方法 m, 类<?> specialCaller) throws IllegalAccessException
invokespecial
指令在明确指定
specialCaller
。该方法处理的类型将是该方法与适当限制接收机类型前缀。(接收器类型将
specialCaller
或亚型。)如果没有设置方法的
accessible
标志,访问检查立即执行的查找类的代表,如果
invokespecial
指令被链接。
以前的方法解决,如果明确指定调用类是不相同的查找类,或者如果该查询对象没有private access权限,访问失败。
返回的方法处理会有variable arity若方法的变量数量修改位(0x0080
)设置。
m
-反射法
specialCaller
名义上的类调用方法
IllegalAccessException
如果访问检查失败或如果方法的变性剂位设置和
asVarargsCollector
失败
NullPointerException
-如果任一参数为空
public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException
newInstance
操作,创建传递给方法的参数处理的一个新的实例构造函数的类。
如果没有设置构造函数的accessible
标志,访问检查立即执行,对查课代表。
返回的方法处理会有variable arity如果构造函数的变量数量修改位(0x0080
)设置。
如果调用返回的方法句柄,则构造函数的类将被初始化,如果它还没有被初始化。
c
-反射的构造函数
IllegalAccessException
如果访问检查失败或如果方法的变性剂位设置和
asVarargsCollector
失败
NullPointerException
-如果参数为空
public MethodHandle unreflectGetter(Field f) throws IllegalAccessException
accessible
标志,访问检查立即执行,对查课代表。
如果字段是静态的,如果调用返回的方法句柄,则字段的类将被初始化,如果它没有被初始化。
f
-反射场
IllegalAccessException
如果访问检查失败
NullPointerException
-如果参数为空
public MethodHandle unreflectSetter(Field f) throws IllegalAccessException
accessible
标志,访问检查立即执行,对查课代表。
如果字段是静态的,如果调用返回的方法句柄,则字段的类将被初始化,如果它没有被初始化。
f
-反射场
IllegalAccessException
如果访问检查失败
NullPointerException
-如果参数为空
public MethodHandleInfo revealDirect(MethodHandle target)
target
-一个直接的方法处理裂缝为符号参考组件
SecurityException
-如果一个安全管理是目前这
refuses access
IllegalArgumentException
-如果目标不是一个直接的方法处理或者访问检查失败
null
NullPointerException
MethodHandleInfo
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.