在学习java9 StringConcatFactory类时,我无法理解为什么使用MethodHandles.publicLookup()跟随代码会引发StringConcatException异常,而如果使用MethodHandles.lookup()则一切正常。

根据查找的Java文档:

“查找-表示具有可访问性的查找上下文
呼叫者的特权”

StringConcatFactory.makeConcat(MethodHandles.publicLookup(),
"abc",MethodType.methodType(String.class));//Exception Here


StringConcatFactory.makeConcat(MethodHandles.lookup(),
"abc", MethodType.methodType(String.class)); //Working fine

我不确定我在哪里弄错了?请帮助我了解这种行为。

最佳答案

makeConcat的Javadoc讲述了第一个参数:

查找表示具有调用者的访问权限的查找上下文
publicLookup返回的查找上下文没有这些特权。

即使您什么也不连接,该异常仍将引发:

MethodType concatType = MethodType.methodType(String.class); // No arguments, returns String
StringConcatFactory.makeConcat(MethodHandles.publicLookup(), "abc", concatType); // Exception

因为上下文的访问权限是在StringConcatFactory#doStringConcat中检查的:
if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
    throw new StringConcatException("Invalid caller: " +
            lookup.lookupClass().getName());
}

上下文需要私有查找模式,而publicLookup没有它:
System.out.println((MethodHandles.publicLookup().lookupModes()
    & MethodHandles.Lookup.PRIVATE) != 0); // false
System.out.println((MethodHandles.lookup().lookupModes()
    & MethodHandles.Lookup.PRIVATE) != 0); // true

08-18 10:34