public static final class MethodHandles.Lookup extends Object
ã¡ãœããã»ãã³ãã«ãäœæããå¿
èŠã®ããã«ãã¯ã¢ããã»ã¯ã©ã¹ã¯ãMethodHandles.lookupãåŒã³åºããŠèªåçšã®ãã¡ã¯ããªãäœæããŸãã Lookupãã¡ã¯ããªã»ãªããžã§ã¯ãã®äœææã«ã¯ãã«ãã¯ã¢ããã»ã¯ã©ã¹ã®ã¢ã€ãã³ãã£ãã£ã決å®ããããã®æ
å ±ãLookupãªããžã§ã¯ãå
ã«ã»ãã¥ã¢ã«æ ŒçŽãããŸãã ãã®åŸãã«ãã¯ã¢ããã»ã¯ã©ã¹(ãŸãã¯ãã®å§è²å
)ã¯ãLookupãªããžã§ã¯ãã®ãã¡ã¯ããªã»ã¡ãœããã䜿ã£ãŠã¢ã¯ã»ã¹ã»ãã§ãã¯ãããã¡ã³ããŒã®ã¡ãœããã»ãã³ãã«ãäœæã§ããŸãã ããã«ã¯ãã«ãã¯ã¢ããã»ã¯ã©ã¹ã«èš±å¯ãããã¡ãœãããã³ã³ã¹ãã©ã¯ã¿ãããã³ãã£ãŒã«ãããã¹ãŠå«ãŸããŸã(privateã®ãã®ãå«ã)ã
Lookupãªããžã§ã¯ãã®ãã¡ã¯ããªã»ã¡ãœããã¯ãã¡ãœãããã³ã³ã¹ãã©ã¯ã¿ãããã³ãã£ãŒã«ãã®ãã¹ãŠã®ã¡ãžã£ãŒãªãŠãŒã¹ã»ã±ãŒã¹ã«å¯Ÿå¿ããŠããŸãã ãã¡ã¯ããªã»ã¡ãœããã«ãã£ãŠäœæãããåã¡ãœããã»ãã³ãã«ã¯ãç¹å®ã®ãã€ãã³ãŒãåäœãšæ©èœçã«åçã§ãã (ãã€ãã³ãŒãåäœã¯ãJava Virtual Machine Specificationãã®ã»ã¯ã·ã§ã³5.4.3.5ã«èšè¿°ãããŠããŸãã) ãããã®ãã¡ã¯ããªã»ã¡ãœãããšãçµæãšãªãã¡ãœããã»ãã³ãã«ã®åäœãšã®å¯Ÿå¿é¢ä¿ã®ãµããªãŒããæ¬¡ã«ç€ºããŸãã
| ã«ãã¯ã¢ããåŒ | ã¡ã³ã㌠| ãã€ãã³ãŒãåäœ |
|---|---|---|
lookup.findGetter(C.class,"f",FT.class) |
FT f; | (T) this.f; |
lookup.findStaticGetter(C.class,"f",FT.class) |
staticFT f; | (T) C.f; |
lookup.findSetter(C.class,"f",FT.class) |
FT f; | this.f = x; |
lookup.findStaticSetter(C.class,"f",FT.class) |
staticFT f; | C.f = arg; |
lookup.findVirtual(C.class,"m",MT) |
T m(A*); | (T) this.m(arg*); |
lookup.findStatic(C.class,"m",MT) |
staticT 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ã¯ãã¡ãœããã»ãã³ãã«ã®ã»ãã®ãã¹ãŠã®åŒæ°ã衚ããŠããŸãã Core Reflection APIã®ã³ãŒãäŸã«å«ãŸããååthisOrNullã¯ãã¢ã¯ã»ã¹å¯Ÿè±¡ã®ã¡ãœããããã£ãŒã«ããstaticã®å Žåã¯nullåç
§ã衚ãããã以å€ã®å Žåã¯thisã衚ããŸãã ååaMethodãaFieldãããã³aConstructorã¯ãæå®ãããã¡ã³ããŒã«å¯Ÿå¿ãããªãã¬ã¯ã·ã§ã³ã»ãªããžã§ã¯ãã衚ããŠããŸãã
æå®ãããã¡ã³ããŒãå¯å€åŒæ°(ã€ãŸãã¡ãœãããŸãã¯ã³ã³ã¹ãã©ã¯ã¿)ã®å Žåãè¿ãããã¡ãœããã»ãã³ãã«ãå¯å€åŒæ°ã«ãªããŸãã ãã®ä»ã®ãã¹ãŠã®å Žåãè¿ãããã¡ãœããã»ãã³ãã«ã¯åºå®åŒæ°ã«ãªããŸãã
ãã£ã¹ã«ãã·ã§ã³: ã«ãã¯ã¢ãããããã¡ãœããã»ãã³ãã«ãšåºç€ãšãªãã¯ã©ã¹ã»ã¡ã³ããŒãšãã€ãã³ãŒãåäœãšã®éã®ç䟡æ§ããããã€ãã®æ¹æ³ã§å£ããããšããããŸãã
Cãã«ãã¯ã¢ããã»ã¯ã©ã¹ã®ããŒããŒããã·ã³ãã«ã§ã¢ã¯ã»ã¹ã§ããªãå Žåã§ããã«ãã¯ã¢ãããæåããããšããããŸã(åçã®JavaåŒããã€ãã»ã³ãŒã宿°ãååšããªãå Žåã§ã)ã
TãŸãã¯MTãã«ãã¯ã¢ããã»ã¯ã©ã¹ã®ããŒããŒããã·ã³ãã«ã§ã¢ã¯ã»ã¹ã§ããªãå Žåã§ããã«ãã¯ã¢ãããæåããããšããããŸãã ããšãã°ãMethodHandle.invokeExactãMethodHandle.invokeã®ã«ãã¯ã¢ããã¯ãèŠæ±ãããåãšã¯ç¡é¢ä¿ã«åžžã«æåããŸãã
CONSTANT_MethodHandle宿°ã§ã®ldcåœä»€ã¯ã»ãã¥ãªãã£ã»ãããŒãžã£ã»ãã§ãã¯ãããŸããã
Lookupã®ãã¡ã¯ããªã»ã¡ãœããå
ã§é©çšãããŸãã ããããCore Reflection APIãšã®éèŠãªéãã§ã(java.lang.reflect.Method.invokeã§ã¯ãã¹ãŠã®åŒåºãã§ããã¹ãŠã®åŒåºãå
ã«å¯ŸããŠã¢ã¯ã»ã¹ã»ãã§ãã¯ãå®è¡ããã)ã
ãã¹ãŠã®ã¢ã¯ã»ã¹ã»ãã§ãã¯ã¯Lookupãªããžã§ã¯ãããå§ãŸããŸããããã®ãªããžã§ã¯ãã§ã¯ãèšé²ãããŠããã«ãã¯ã¢ããã»ã¯ã©ã¹ãšãã¹ãŠã®ã¡ãœããã»ãã³ãã«äœæèŠæ±ãšãç
§åãããŸãã åäžã®Lookupãªããžã§ã¯ãã䜿ã£ãŠä»»æã®æ°ã®ã¢ã¯ã»ã¹ã»ãã§ãã¯æžã¿ã¡ãœããã»ãã³ãã«ãäœæã§ããŸã(ãã¹ãŠã¯åäžã®ã«ãã¯ã¢ããã»ã¯ã©ã¹ã«åºã¥ããŠãã§ãã¯ããã)ã
Lookupãªããžã§ã¯ãã¯ãã»ãã®ä¿¡é Œã§ããã³ãŒã(ã¡ã¿ãªããžã§ã¯ãã»ãããã³ã«ãªã©)ãšå
±æã§ããŸãã å
±æLookupãªããžã§ã¯ãã¯ãã¡ãœããã»ãã³ãã«ãäœæããæ©èœããã«ãã¯ã¢ããã»ã¯ã©ã¹ã®privateã¡ã³ããŒã«å§è²ããŸãã ç¹æš©ä»ãã³ãŒããLookupãªããžã§ã¯ãã䜿çšããå Žåã§ããã¢ã¯ã»ã¹ã»ãã§ãã¯ã¯å
ã®ã«ãã¯ã¢ããã»ã¯ã©ã¹ã®ç¹æš©ã«éå®ãããŸãã
ã«ãã¯ã¢ããã倱æããããšããããŸããå
å«ããã¯ã©ã¹ã«ã«ãã¯ã¢ããã»ã¯ã©ã¹ããã¢ã¯ã»ã¹ã§ããªããç®çã®ã¯ã©ã¹ã»ã¡ã³ããŒãèŠã€ãããªããç®çã®ã¯ã©ã¹ã»ã¡ã³ããŒã«ã«ãã¯ã¢ããã»ã¯ã©ã¹ããã¢ã¯ã»ã¹ã§ããªãããŸãã¯ã«ãã¯ã¢ããã»ãªããžã§ã¯ããä¿¡é ŒãããŠããªãããã¡ã³ããŒã«ã¢ã¯ã»ã¹ããã§ãã ãããã®å Žåãã詊ã¿ãããã«ãã¯ã¢ããããReflectiveOperationExceptionãã¹ããŒãããŸãã å
·äœçãªã¯ã©ã¹ã¯æ¬¡ã®ããããã«ãªããŸãã
äžè¬ã«ãã¡ãœããMãã¡ãœããã»ãã³ãã«ãã«ãã¯ã¢ããã§ããæ¡ä»¶ã¯ãã«ãã¯ã¢ããã»ã¯ã©ã¹ãMãžã®åŒåºããã³ã³ãã€ã«ãæ€èšŒã解決ã§ããæ¡ä»¶ã»ã©å¶éçã§ã¯ãããŸããã JVMãNoSuchMethodErrorãªã©ã®äŸå€ãã¹ããŒãããšããã¡ãœããã»ãã³ãã«ã»ã«ãã¯ã¢ããã¯äžè¬ã«NoSuchMethodExceptionãªã©ã®å¯Ÿå¿ãããã§ãã¯äŸå€ãã¹ããŒããŸãã ãŸããã«ãã¯ã¢ããã®çµæå®è¡ãããã¡ãœããã»ãã³ãã«åŒåºãã®å¹æã¯ãã³ã³ãã€ã«ãæ€èšŒããã³è§£æ±ºãããMåŒåºããå®è¡ããã®ãšãŸã£ããåãã§ãã ãã£ãŒã«ããšã³ã³ã¹ãã©ã¯ã¿ã«ã€ããŠãåãããšãèšããŸãã
ãã£ã¹ã«ãã·ã§ã³: ã¢ã¯ã»ã¹ã»ãã§ãã¯ã¯ãååä»ãã®ãªãã¬ã¯ããããã¡ãœãããã³ã³ã¹ãã©ã¯ã¿ãããã³ãã£ãŒã«ãã«ã®ã¿é©çšãããŸãã MethodHandle.asTypeãªã©ãä»ã®ã¡ãœããã»ãã³ãã«äœæã¡ãœããã¯ãã¢ã¯ã»ã¹ã»ãã§ãã¯ãå¿
èŠãšãããLookupãªããžã§ã¯ãããç¬ç«ããŠäœ¿çšãããŸãã
ç®çã®ã¡ã³ããŒãprotectedã§ããå Žåãã«ãã¯ã¢ããã»ã¯ã©ã¹ãç®çã®ã¡ã³ããŒãšåãããã±ãŒãžã«å«ãŸããŠãããããã®ã¡ã³ããŒãç¶æ¿ããŠããå¿
èŠããããšããèŠä»¶ãªã©ãéåžžã®JVMã«ãŒã«ãé©çšãããŸãã (ãJava Virtual Machine Specificationãã®ã»ã¯ã·ã§ã³4.9.2ã5.4.3.5ãããã³6.4ãåç
§ããŠãã ããã) ãŸããç®çã®ã¡ã³ããŒãå¥ã®ããã±ãŒãžå
ã«ããéstaticãã£ãŒã«ããŸãã¯ã¡ãœããã§ããå Žåãçµæãšãªãã¡ãœããã»ãã³ãã«ã¯ã«ãã¯ã¢ããã»ã¯ã©ã¹ãŸãã¯ãã®ããããã®ãµãã¯ã©ã¹ã®ãªããžã§ã¯ãã«ããé©çšãããªãå¯èœæ§ããããŸãã ãã®èŠä»¶ã¯ãå
é ã®thisãã©ã¡ãŒã¿ã®åãC (å¿
ãã«ãã¯ã¢ããã»ã¯ã©ã¹ã®ã¹ãŒããŒã»ã¯ã©ã¹ã«ãªã)ããã«ãã¯ã¢ããã»ã¯ã©ã¹èªäœã«ãããŒå€æããããšã§åŒ·å¶ãããŸãã
JVMã¯åæ§ã®èŠä»¶ãinvokespecialåœä»€ã«é©çšããŸã(ã¬ã·ãŒãåŒæ°ã解決æžã¡ãœããããã³çŸåšã®ã¯ã©ã¹ã«äžèŽããå¿
èŠããã)ã ããã«ãã®èŠä»¶ã¯ãå
é ãã©ã¡ãŒã¿ã®åãçµæã®ã¡ãœããã»ãã³ãã«ã«ãããŒå€æããããšã§é©çšãããŸãã (ãJava Virtual Machine Specificationãã®ã»ã¯ã·ã§ã³4.10.1.9ãåç
§ããŠãã ããã)
JVMã¯ãã³ã³ã¹ãã©ã¯ã¿ããã³staticã€ãã·ã£ã©ã€ã¶ã»ãããã¯ããç¹æ®ãªåå("<init>"ãš"<clinit>")ãæã€å
éšã¡ãœãããšããŠè¡šããŸãã åŒåºãåœä»€ã®å
éšæ§æã¯ããã®ãããªå
éšã¡ãœãããéåžžã®ã¡ãœããã®ããã«åç
§ããããšãèš±å¯ããŸãããJVMãã€ãã³ãŒãã»ããªãã¡ã€ã¢ã¯ããããæåŠããŸãã ãã®ãããªå
éšã¡ãœãããã«ãã¯ã¢ããã¯NoSuchMethodExceptionãçæããŸãã
å Žåã«ãã£ãŠã¯ããã¹ããããã¯ã©ã¹éã®ã¢ã¯ã»ã¹ã¯ãJavaã³ã³ãã€ã©ããå¥ã®ã¯ã©ã¹ã®privateã¡ãœããã«ã¢ã¯ã»ã¹ããããã®ã©ãããŒã»ã¡ãœãããåããããã»ã¬ãã«ã®å®£èšå
ã§äœæããããšã«ãã£ãŠåŸãããŸãã ããšãã°ããã¹ããããã¯ã©ã¹C.Dã¯ã»ãã®é¢é£ã¯ã©ã¹(CãC.D.EãC.Bãªã©)ã®å
éšã®privateã¡ã³ããŒã«ã¢ã¯ã»ã¹ã§ããŸãããJavaã³ã³ãã€ã©ããããã®é¢é£ã¯ã©ã¹å
ã§ã©ãããŒã»ã¡ãœãããçæããªããã°ãããªãå¯èœæ§ããããŸãã ãã®ãããªå ŽåãC.Eã®Lookupãªããžã§ã¯ãã¯ãããã®privateã¡ã³ããŒã«ã¢ã¯ã»ã¹ã§ããŸããã ãã®å¶éã®åé¿æ¹æ³ã®1ã€ãLookup.inã¡ãœããã§ãããããã䜿ãããšã§ãç¹æš©ã¬ãã«ãç¹å¥ã«äžããããšãªãC.Eã®ã«ãã¯ã¢ãããããããã»ãã®ã¯ã©ã¹ã®ããããã®ã«ãã¯ã¢ããã«å€æã§ããŸãã
æå®ãããã«ãã¯ã¢ããã»ãªãã»ããã«èš±å¯ãããã¢ã¯ã»ã¹ã¯ããã®lookupModesã»ããã«åºã¥ããŠãã«ãã¯ã¢ããã»ã¯ã©ã¹ããéåžžã¢ã¯ã»ã¹ã§ããã¡ã³ããŒã»ãµãã»ããã«å¶éãããå ŽåããããŸãã ããšãã°ãpublicLookupã¡ãœãããçæããã«ãã¯ã¢ããã»ãªããžã§ã¯ãã¯ãpublicã¯ã©ã¹ã®publicã¡ã³ããŒãžã®ã¢ã¯ã»ã¹ã®ã¿ãèš±å¯ãããŸãã åŒåºãå
äŸåã¡ãœããlookupã¯ããµããŒããããŠãããã¹ãŠã®ãã€ãã³ãŒãåäœããšãã¥ã¬ãŒããããåŒåºãå
ã¯ã©ã¹ã«é¢é£ããããããæ©èœãæã€ã«ãã¯ã¢ããã»ãªããžã§ã¯ããçæããŸãã ãŸããLookup.inã¡ãœããã¯å
ã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã»ã¢ãŒããå°ãªãã«ãã¯ã¢ããã»ãªããžã§ã¯ããçæã§ããŸãã
privateã¢ã¯ã»ã¹ã®ãã£ã¹ã«ãã·ã§ã³: ã«ãã¯ã¢ããã»ã¢ãŒãã«privateã¡ã³ããŒã«ã¢ã¯ã»ã¹ããå¯èœæ§ãå«ãŸããå Žåããã®ã«ãã¯ã¢ããã¯privateã¢ã¯ã»ã¹ãæã€ãšèšããŸãã ããã¥ã¡ã³ãå
ã®é¢é£ã¡ãœããã«èšè¿°ãããŠããããã«ãprivateã¢ã¯ã»ã¹ãæã€ã«ãã¯ã¢ããã®ã¿ãæ¬¡ã®æ©èœãæã¡ãŸãã
Class.forNameãªã©)ãåŒã³åºãã¡ãœããã»ãã³ãã«ãäœæãã
invokespecialåœä»€ããšãã¥ã¬ãŒãããã¡ãœããã»ãã³ãã«ãäœæãã
å§è²ãããã«ãã¯ã¢ããã»ãªããžã§ã¯ããäœæãã
ãããã®ããšãèš±å¯ãããã®ã¯ãprivateã¢ã¯ã»ã¹ãæã€ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããå ã®ã¯ã©ã¹ãŸã§å®å šã«ãã©ãããšãã§ãããã®ãã€ãã³ãŒãåäœããã³Javaèšèªã¢ã¯ã»ã¹æš©ãã¡ãœããã»ãã³ãã«ã確å®ã«å€æããŠãšãã¥ã¬ãŒãã§ãããšããäºå®ã®çµæã§ãã
Classãªããžã§ã¯ããžã®åç
§ã䜿çšå¯èœã§ããããããä»»æã®ã¯ã©ã¹å
ã®ã¡ãœãããæ€çŽ¢ã§ããŸãã ãã®ãããªã¯ãã¹ããŒããŒåç
§ã¯ãCore Reflection APIã§ãå¯èœã§ãããinvokestaticãgetfieldãªã©ã®ãã€ãã»ã³ãŒãåœä»€ã§ã¯äžå¯èœã§ãã ã¢ããªã±ãŒã·ã§ã³å
ã§ãã®ãããªã¯ãã¹ããŒããŒåç
§ããã§ãã¯ã§ããããã«ããããã®ã»ãã¥ãªãã£ã»ãããŒãžã£APIãååšããŸãã ãããã®ãã§ãã¯ã¯ãMethodHandles.Lookup APIãš(Classäžã«ååšãã) Core Reflection APIã®äž¡æ¹ã«é©çšãããŸãã
ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšããå Žåãã¡ã³ããŒã»ã«ãã¯ã¢ããã«å¯ŸããŠè¿œå ã®ãã§ãã¯ãè¡ãããŸãã ã»ãã¥ãªãã£ã»ãããŒãžã£ã«å¯ŸããŠ1åãã3åã®åŒåºããè¡ãããŸãã ãããã®åŒåºãã®ãããããSecurityExceptionãã¹ããŒããããšã§ã¢ã¯ã»ã¹ãæåŠã§ããŸãã smgrãã»ãã¥ãªãã£ã»ãããŒãžã£ãšããŠãlookcãçŸåšã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã®ã«ãã¯ã¢ããã»ã¯ã©ã¹ãšããŠãrefcãã¡ã³ããŒãæ€çŽ¢ããå
å«ã¯ã©ã¹ãšããŠãdefcãã¡ã³ããŒãå®éã«å®çŸ©ãããã¯ã©ã¹ãšããŠå®çŸ©ããŠãã ããã å€lookcã¯ãçŸåšã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ããprivateã¢ã¯ã»ã¹ãæããªãå Žåã¯ååšããªããšããŠå®çŸ©ãããŸãã æ¬¡ã®ã«ãŒã«ã«åŸã£ãŠåŒåºããè¡ãããŸãã
lookcãååšããªãå ŽåããŸãã¯ãã®ã¯ã©ã¹ã»ããŒããŒãrefcã®ã¯ã©ã¹ã»ããŒããŒãšåãã§ããã®ç¥å
ã§ããªãå Žåã¯ãsmgr.checkPackageAccess(refcPkg)ãåŒã³åºãããŸã(refcPkgã¯refcã®ããã±ãŒãž)ã
lookcãååšããªãå Žåã¯ãRuntimePermission("accessDeclaredMembers")ã§smgr.checkPermissionãåŒã³åºãããŸãã
lookcãååšãããdefcãšrefcãç°ãªãå Žåã¯ãsmgr.checkPackageAccess(defcPkg)ãåŒã³åºãããŸã(defcPkgã¯defcã®ããã±ãŒãž)ã
åŒåºãå äŸåã¡ãœããã®ã¡ãœããã»ãã³ãã«ãèŠæ±ãããå Žåã¯ããã€ãã³ãŒãåäœã®äžè¬ã«ãŒã«ãé©çšãããŸãããã«ãã¯ã¢ããã»ã¯ã©ã¹ã¯ç¹å¥ãªæ¹æ³ã§èæ ®ãããŸãã çµæã®ã¡ãœããã»ãã³ãã«ã¯ã«ãã¯ã¢ããã»ã¯ã©ã¹ã«å«ãŸããŠããåœä»€ããåŒã³åºãããããã«åäœããåŒåºãå äŸåã¡ãœããã¯ã«ãã¯ã¢ããã»ã¯ã©ã¹ãæ€åºããŸãã (äžæ¹ãã¡ãœããã»ãã³ãã«ã®ã€ã³ããŒã«ã¯ç¡èŠãããŸãã) ãããã£ãŠãåŒåºãå äŸåã¡ãœããã®å Žåã¯ãã«ãã¯ã¢ããã»ã¯ã©ã¹ããšã«ã¡ãœããã»ãã³ãã«ã®åäœãç°ãªãå¯èœæ§ããããŸãã
ã«ãã¯ã¢ããã»ãªããžã§ã¯ããpublicLookup()ã®å ŽåããŸãã¯privateã¢ã¯ã»ã¹ãªãã®ããã€ãã®ä»ã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã®å Žåããã®ã«ãã¯ã¢ããã»ã¯ã©ã¹ã¯ç¡èŠãããŸãã ãã®ãããªå ŽåãåŒåºãå
äŸåã¡ãœããã»ãã³ãã«ãäœæã§ãããã¢ã¯ã»ã¹ã¯çŠæ¢ãããã«ãã¯ã¢ããã¯IllegalAccessExceptionã§å€±æããŸãã
ãã£ã¹ã«ãã·ã§ã³: ããšãã°ãåŒåºãå
äŸåã¡ãœããClass.forName(x)ã¯ããããåŒã³åºãã¯ã©ã¹ã®ã¯ã©ã¹ã»ããŒããŒã«å¿ããŠãè¿ãããã¯ã©ã¹ãç°ãªã£ãããã¹ããŒãããäŸå€ãç°ãªã£ããããå¯èœæ§ããããŸãã Class.forNameã®publicã«ãã¯ã¢ããã¯å€±æããŸãããã®ãã€ãã³ãŒãåäœãå€å¥ããããã®åŠ¥åœãªæ¹æ³ããªãããã§ãã
åºç¯å²ãªå
±æã®ããã«ã¡ãœããã»ãã³ãã«ããã£ãã·ã¥ããã¢ããªã±ãŒã·ã§ã³ã®å Žåã¯ãpublicLookup()ã䜿çšããŠã¡ãœããã»ãã³ãã«ãäœæããããšããèŠãããŸãã Class.forNameã®ã«ãã¯ã¢ãããããå Žåãããã¯å€±æããã¢ããªã±ãŒã·ã§ã³ã¯ãã®å Žåã«é©åãªã¢ã¯ã·ã§ã³ãåãå¿
èŠããããŸãã ããšãã°ãåŸã®ã«ãã¯ã¢ãã(ããããããŒãã¹ãã©ããã»ã¡ãœããã®åŒã³åºãäž)ãåŒåºãå
åºæã®è奿
å ±ãçµã¿èŸŒãããšã§ãã¡ãœãããã¢ã¯ã»ã¹å¯èœã«ããã¢ã¯ã·ã§ã³ã§ãã
颿°MethodHandles.lookupã¯åŒåºãå
äŸåãªã®ã§ãã«ãã¯ã¢ããçšã®å®å
šãªåºç€ãååšã§ããŸãã JSR 292 APIå
ã®ä»ã®ã»ãšãã©ãã¹ãŠã®ã¡ãœããã¯ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã«äŸåããŠã¢ã¯ã»ã¹èŠæ±ããã§ãã¯ããŸãã
| 修食åãšå | ãã£ãŒã«ã | 説æ |
|---|---|---|
static int |
PACKAGE |
packageã¢ã¯ã»ã¹(ããã©ã«ãã»ã¢ã¯ã»ã¹)ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã |
static int |
PRIVATE |
privateã¢ã¯ã»ã¹ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã |
static int |
PROTECTED |
protectedã¢ã¯ã»ã¹ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã |
static int |
PUBLIC |
publicã¢ã¯ã»ã¹ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã |
| 修食åãšå | ã¡ãœãã | 説æ |
|---|---|---|
MethodHandle |
bind(Object receiver, String name, MethodType type) |
éstaticã¡ãœããã®æ©æãã€ã³ãã»ã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findConstructor(Class<?> refc, MethodType type) |
æå®ãããåã®ã³ã³ã¹ãã©ã¯ã¿ã䜿ã£ãŠãªããžã§ã¯ãã®äœæãšåæåãè¡ãã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findGetter(Class<?> refc, String name, Class<?> type) |
éstaticãã£ãŒã«ãã«å¯Ÿããèªåãã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findSetter(Class<?> refc, String name, Class<?> type) |
éstaticãã£ãŒã«ãã«å¯ŸããæžèŸŒã¿ã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) |
ä»®æ³ã¡ãœããã®æ©æã«ãã€ã³ããããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findStatic(Class<?> refc, String name, MethodType type) |
staticã¡ãœããã®ã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findStaticGetter(Class<?> refc, String name, Class<?> type) |
staticãã£ãŒã«ãã«å¯Ÿããèªåãã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findStaticSetter(Class<?> refc, String name, Class<?> type) |
staticãã£ãŒã«ãã«å¯ŸããæžèŸŒã¿ã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
findVirtual(Class<?> refc, String name, MethodType type) |
ä»®æ³ã¡ãœããã®ã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandles.Lookup |
in(Class<?> requestedLookupClass) |
æå®ãããæ°ããã«ãã¯ã¢ããã»ã¯ã©ã¹ã§ã«ãã¯ã¢ãããäœæããŸãã
|
Class<?> |
lookupClass() |
ã«ãã¯ã¢ãããå®è¡ããŠããã¯ã©ã¹ã瀺ããŸãã
|
int |
lookupModes() |
ãã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ããã©ã®ã¢ã¯ã»ã¹ä¿è·ã¯ã©ã¹ã®ã¡ã³ããŒãçæã§ãããã瀺ããŸãã
|
MethodHandleInfo |
revealDirect(MethodHandle target) |
ãã®åç
§ãªããžã§ã¯ããŸãã¯é¡äŒŒã®ãªããžã§ã¯ãã«ãã£ãŠäœæãããçŽæ¥ã¡ãœããã»ãã³ãã«ãè§£èªããŸãã
|
String |
toString() |
ã«ãã¯ã¢ããã®å®è¡å
ãšãªãã¯ã©ã¹ã®ååã衚瀺ããŸãã
|
MethodHandle |
unreflect(Method m) |
ã«ãã¯ã¢ããã»ã¯ã©ã¹ãã¢ã¯ã»ã¹æš©ãæã€å Žåã«ãmãžã®çŽæ¥ã¡ãœããã»ãã³ãã«ãäœæããŸãã
|
MethodHandle |
unreflectConstructor(Constructor<?> c) |
ãªãã¬ã¯ããããã³ã³ã¹ãã©ã¯ã¿ã®ã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
unreflectGetter(Field f) |
ãªãã¬ã¯ãããããã£ãŒã«ãã«å¯Ÿããèªåãã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
unreflectSetter(Field f) |
ãªãã¬ã¯ãããããã£ãŒã«ãã«å¯ŸããæžèŸŒã¿ã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
MethodHandle |
unreflectSpecial(Method m, Class<?> specialCaller) |
ãªãã¬ã¯ããããã¡ãœããã®ã¡ãœããã»ãã³ãã«ãçæããŸãã
|
public static final int PUBLIC
publicã¢ã¯ã»ã¹ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã å€0x01ã¯ããŸããŸãpublic 修食åãããã®å€ãšåãã«ãªã£ãŠããŸãã public static final int PRIVATE
privateã¢ã¯ã»ã¹ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã å€0x02ã¯ããŸããŸãprivate 修食åãããã®å€ãšåãã«ãªã£ãŠããŸãã public static final int PROTECTED
protectedã¢ã¯ã»ã¹ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã å€0x04ã¯ããŸããŸãprotected 修食åãããã®å€ãšåãã«ãªã£ãŠããŸãã public static final int PACKAGE
packageã¢ã¯ã»ã¹(ããã©ã«ãã»ã¢ã¯ã»ã¹)ã衚ãåäžãããã»ãã¹ã¯(lookupModesã®çµæã«å¯äžããå¯èœæ§ããã)ã å€ã¯0x08ã§ãããããã¯ãç¹å®ã®ã©ã®ä¿®é£Ÿåãããã«ããæå³ã®ããããã¡ã§ã¯å¯Ÿå¿ããŸããã public Class<?> lookupClass()
ãã®ã¯ã©ã¹ã¯æå€§ã¬ãã«ã®ã¢ã¯ã»ã¹æš©ãæé»çã«ç€ºããŸãããépublicã¡ã³ããŒã«ã¢ã¯ã»ã¹ã§ãããã©ãããå¶åŸ¡ãããããã»ãã¹ã¯lookupModesã«ãããã¢ã¯ã»ã¹æš©ãããã«å¶éãããå¯èœæ§ããããŸãã
public int lookupModes()
åŒåºãå ã®ã¯ã©ã¹äžã§æ°ããäœæãããã«ãã¯ã¢ããã»ãªããžã§ã¯ãã§ã¯ãååšãããã¹ãŠã®ããããèšå®ãããŸãããããã¯ãåŒåºãå ã®ã¯ã©ã¹ã¯èªèº«ã®ãã¹ãŠã®ã¡ã³ããŒã«ã¢ã¯ã»ã¹ã§ããããã§ãã 以åã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããäœæãããæ°ããã«ãã¯ã¢ããã»ã¯ã©ã¹äžã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã§ã¯ãããã€ãã®ã¢ãŒãã»ãããããŒãã«èšå®ãããŠããå¯èœæ§ããããŸãã ãã®ç®çã¯ãæ°ããã«ãã¯ã¢ããã»ãªããžã§ã¯ãçµç±ã§ã®ã¢ã¯ã»ã¹ãå¶éããå ã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ããšæ°ããã«ãã¯ã¢ããã»ã¯ã©ã¹ã®äž¡æ¹ããå°éå¯èœãªååã ãã«ã¢ã¯ã»ã¹ã§ããããã«ããããšã§ãã
public MethodHandles.Lookup in(Class<?> requestedLookupClass)
lookupClassãšããŠå ±åããŸãã
ãã ããçµæãšãªãLookupãªããžã§ã¯ãã¯ãå
ã®ãªããžã§ã¯ããšåç以äžã®ã¢ã¯ã»ã¹æ©èœããæããªãããšãä¿èšŒãããŸãã å
·äœçã«ã¯ãã¢ã¯ã»ã¹æ©èœã次ã®ããã«å€±ãããå¯èœæ§ããããŸãã
requestedLookupClass - æ°ããã«ãã¯ã¢ããã»ãªããžã§ã¯ãçšã«èŠæ±ãããã«ãã¯ã¢ããã»ã¯ã©ã¹NullPointerException - åŒæ°ãnullã®å Žåpublic String toString()
Class.getNameããå ±åããããã®ã§ãã) ãã®ã«ãã¯ã¢ããã«èš±å¯ãããã¢ã¯ã»ã¹ã«å¶éãããå Žåããã®ããšã瀺ãããã«ãã¹ã©ãã·ã¥ãšããŒã¯ãŒãã§æ§æãããæ¥å°ŸèŸãã¯ã©ã¹åã«è¿œå ãããŸãã ããŒã¯ãŒãã¯èš±å¯ãããæåŒ·ã®ã¢ã¯ã»ã¹ã衚ããŠãããæ¬¡ã®ããã«éžæãããŸãã
MethodHandles.lookupããååŸããããªããžã§ã¯ãã®å Žåã ãã§ãã Lookup.inã§äœæããããªããžã§ã¯ãã§ã¯åžžã«ã¢ã¯ã»ã¹ãå¶éãããæ¥å°ŸèŸã衚瀺ãããŸãã
(protectedã¢ã¯ã»ã¹ãprivateã¢ã¯ã»ã¹ãã匷ããšããã®ã¯ãå¥åŠã«æãããããããŸããã packageã¢ã¯ã»ã¹ããç¬ç«ããŠèŠãå Žåãprotectedã¢ã¯ã»ã¹ãæåã«å€±ããããã®ã«ãªããŸãããããã¯ãåŒåºãå ãšåŒåºãå ã®éã«çŽæ¥çãªãµãã¯ã©ã¹é¢ä¿ãå¿ èŠã«ãªãããã§ãã)
toStringãã¯ã©ã¹Objectin(java.lang.Class<?>)public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
findVirtualãfindSpecialã®ããã«ãã¡ãœããã»ãã³ãã«ã®åã«è¿œå ã®ã¬ã·ãŒãåŒæ°ãæ¿å
¥ãããããšã¯ãããŸããã) ãã®ã¡ãœãããšãã®ãã¹ãŠã®åŒæ°åã«ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããã(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 - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
refc)ã远å ãããã®ã«ãªããŸãã ãã®ã¡ãœãããšãã®ãã¹ãŠã®åŒæ°åã«ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãã
ãã³ãã«ã¯åŒåºãæã«ãæåã®åŒæ°ãã¬ã·ãŒããšã¿ãªãããã®ã¬ã·ãŒãã®åã§ãã£ã¹ãããããŠã©ã®ã¡ãœããå®è£
ã«å
¥ãããæ±ºå®ããŸãã (ãã®ãã£ã¹ãããã»ã¢ã¯ã·ã§ã³ã¯ãinvokevirtualãŸãã¯invokeinterfaceåœä»€ã«ãã£ãŠå®è¡ãããã¢ã¯ã·ã§ã³ãšåäžã§ãã)
ã«ãã¯ã¢ããã»ã¯ã©ã¹ãã¡ã³ããŒã«ã¢ã¯ã»ã¹ããå®å
šãªæš©éãæã£ãŠããå Žåãæåã®åŒæ°ã®åã¯refcã«ãªããŸãã ãã以å€ã®å Žåãã¡ã³ããŒã¯protectedã§ããå¿
èŠããããæåã®åŒæ°ã®åã¯ã«ãã¯ã¢ããã»ã¯ã©ã¹ã«å¶éãããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããã(0x0080)ãèšå®ãããŠããå Žåã ãã§ãã
invokevirtualåœä»€ãšfindVirtualã«ãã£ãŠçæãããã¡ãœããã»ãã³ãã«ãšã®éã®äžè¬çãªç䟡æ§ã®ããã«ãã¯ã©ã¹ãMethodHandleã§ååæååãinvokeExactãŸãã¯invokeã®å Žåã¯ãçµæã®ã¡ãœããã»ãã³ãã«ã¯åãtypeåŒæ°ã®MethodHandles.exactInvokerãŸãã¯MethodHandles.invokerã§çæããããã®ãšåçã§ãã äŸ:
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 - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException
èŠæ±ããåã®æ»ãå€ã®åã¯voidã§ãªããã°ãããŸããã (ããã¯ãJVMã®ã³ã³ã¹ãã©ã¯ã¿åèšè¿°åã®æ±ãã«æºæ ããŠããŸãã)
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã³ã³ã¹ãã©ã¯ã¿ã®å¯å€åŒæ°ä¿®é£Ÿåããã(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 - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException
specialCallerå
ã®invokespecialåœä»€ããåŒã³åºããããã®ããã«ãã¬ã·ãŒãã§ã®ã¡ãœããã®ãªãŒããŒã©ã€ãã»ãã§ãã¯ããã€ãã¹ããŸãã ã¡ãœããã»ãã³ãã«ã®åã¯ã¡ãœããã®ãã®ã§ãé©åã«å¶éãããã¬ã·ãŒãåã远å ãããŸãã (ã¬ã·ãŒãåã¯specialCallerãŸãã¯ãµãã¿ã€ãã§ãã) ãã®ã¡ãœãããšãã®ãã¹ãŠã®åŒæ°åã«ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãã
ã¡ãœãã解決ã®åã«ãæç€ºçã«æå®ãããåŒåºãå ã¯ã©ã¹ãã«ãã¯ã¢ããã»ã¯ã©ã¹ãšåäžã§ãªãå ŽåããŸãã¯ãã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ããprivateã¢ã¯ã»ã¹ç¹æš©ãæããªãå Žåã¯ãã¢ã¯ã»ã¹ã倱æããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããã(0x0080)ãèšå®ãããŠããå Žåã ãã§ãã
(ããŒã: "<init>"ãšããJVMå
éšã¡ãœããã¯ãç¹æ®ãªç°å¢ã§ã¯invokespecialåœä»€ã¯ããããåç
§ã§ããŸããããã®APIã§ã¯å¯èŠã§ã¯ãããŸããã å®å
šãªæ¹æ³ã§ã€ã³ã¹ã¿ã³ã¹åæåã¡ãœããã«ã¢ã¯ã»ã¹ããã«ã¯ã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 - ã¡ãœããã®åå(ã<init>ãã§ãã£ãŠã¯ãããªã)type - ã¡ãœããã®å(ã¬ã·ãŒãåŒæ°ã¯å«ãŸãªã)specialCaller - invokespecialãå®è¡ãããææ¡ãããåŒåºãå
ã¯ã©ã¹NoSuchMethodException - ã¡ãœãããååšããªãå ŽåIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããããèšå®ãããŠããŠasVarargsCollectorã倱æããå ŽåSecurityException - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc - ã¡ãœããã®ã¢ã¯ã»ã¹å
ãšãªãã¯ã©ã¹ãŸãã¯ã€ã³ã¿ãã§ãŒã¹name - ãã£ãŒã«ãã®ååtype - ãã£ãŒã«ãã®åNoSuchFieldException - ãã£ãŒã«ããååšããªãå ŽåIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ãã£ãŒã«ããstaticã®å ŽåSecurityException - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc - ã¡ãœããã®ã¢ã¯ã»ã¹å
ãšãªãã¯ã©ã¹ãŸãã¯ã€ã³ã¿ãã§ãŒã¹name - ãã£ãŒã«ãã®ååtype - ãã£ãŒã«ãã®åNoSuchFieldException - ãã£ãŒã«ããååšããªãå ŽåIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ãã£ãŒã«ããstaticã®å ŽåSecurityException - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
è¿ãããã¡ãœããã»ãã³ãã«ãåŒã³åºãããå Žåããã®ãã£ãŒã«ãã®ã¯ã©ã¹ã¯åæåãããŸã(ãŸã åæåãããŠããªãå Žå)ã
refc - ã¡ãœããã®ã¢ã¯ã»ã¹å
ãšãªãã¯ã©ã¹ãŸãã¯ã€ã³ã¿ãã§ãŒã¹name - ãã£ãŒã«ãã®ååtype - ãã£ãŒã«ãã®åNoSuchFieldException - ãã£ãŒã«ããååšããªãå ŽåIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ãã£ãŒã«ããstaticã§ãªãå ŽåSecurityException - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
è¿ãããã¡ãœããã»ãã³ãã«ãåŒã³åºãããå Žåããã®ãã£ãŒã«ãã®ã¯ã©ã¹ã¯åæåãããŸã(ãŸã åæåãããŠããªãå Žå)ã
refc - ã¡ãœããã®ã¢ã¯ã»ã¹å
ãšãªãã¯ã©ã¹ãŸãã¯ã€ã³ã¿ãã§ãŒã¹name - ãã£ãŒã«ãã®ååtype - ãã£ãŒã«ãã®åNoSuchFieldException - ãã£ãŒã«ããååšããªãå ŽåIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ãã£ãŒã«ããstaticã§ãªãå ŽåSecurityException - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
defcå
ã§ã¯ãæå®ãããååãšåãæã€ã¡ãœããã«ã«ãã¯ã¢ããã»ã¯ã©ã¹ããã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãã ãã®ã¡ãœãããšãã®ãã¹ãŠã®åŒæ°åã«ã«ãã¯ã¢ããã»ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãã ã¡ãœããã»ãã³ãã«ã®åã¯ã¡ãœããã®åã§ããã远å ã®ã¬ã·ãŒãã»ãã©ã¡ãŒã¿ã¯äžåæ¿å
¥ãããŸããã æå®ãããã¬ã·ãŒããã¡ãœããã»ãã³ãã«ã«ãã€ã³ãããããããã¡ãœããã»ãã³ãã«ãåŒã³åºããããã³ã«èŠæ±ãããã¡ãœãããæå®ãããã¬ã·ãŒãäžã§åŒã³åºãããããã«ãªããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããã(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 - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å ŽåMethodHandle.bindTo(java.lang.Object)ãfindVirtual(java.lang.Class<?>, java.lang.String, java.lang.invoke.MethodType)public MethodHandle unreflect(Method m) throws IllegalAccessException
accessibleãã©ã°ãèšå®ãããŠããªãå Žåãã«ãã¯ã¢ããã»ã¯ã©ã¹ã«ä»£ãã£ãŠå³åº§ã«ã¢ã¯ã»ã¹ã»ãã§ãã¯ãå®è¡ãããŸãã mãpublicã§ãªãå Žåãçµæãšãªããã³ãã«ãä¿¡é Œã§ããªãçžæãšå
±æããªãã§ãã ããã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããã(0x0080)ãèšå®ãããŠããå Žåã ãã§ãã
mãstaticã§ãè¿ãããã¡ãœããã»ãã³ãã«ãåŒã³åºãããå Žåããã®ã¡ãœããã®ã¯ã©ã¹ã¯åæåãããŸã(ãŸã åæåãããŠããªãå Žå)ã
m - ãªãã¬ã¯ããããã¡ãœããIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããããèšå®ãããŠããŠasVarargsCollectorã倱æããå ŽåNullPointerException - åŒæ°ãnullã®å Žåpublic MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException
specialCallerå
ã®invokespecialåœä»€ããåŒã³åºããããã®ããã«ãã¬ã·ãŒãã§ã®ã¡ãœããã®ãªãŒããŒã©ã€ãã»ãã§ãã¯ããã€ãã¹ããŸãã ã¡ãœããã»ãã³ãã«ã®åã¯ã¡ãœããã®ãã®ã§ãé©åã«å¶éãããã¬ã·ãŒãåã远å ãããŸãã (ã¬ã·ãŒãåã¯specialCallerãŸãã¯ãµãã¿ã€ãã§ãã) ã¡ãœããã®accessibleãã©ã°ãèšå®ãããŠããªãå Žåãinvokespecialåœä»€ããªã³ã¯ãããŠãããã®ããã«ãã«ãã¯ã¢ããã»ã¯ã©ã¹ã«ä»£ãã£ãŠå³åº§ã«ã¢ã¯ã»ã¹ã»ãã§ãã¯ãå®è¡ãããŸãã
ã¡ãœãã解決ã®åã«ãæç€ºçã«æå®ãããåŒåºãå ã¯ã©ã¹ãã«ãã¯ã¢ããã»ã¯ã©ã¹ãšåäžã§ãªãå ŽåããŸãã¯ãã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ããprivateã¢ã¯ã»ã¹ç¹æš©ãæããªãå Žåã¯ãã¢ã¯ã»ã¹ã倱æããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããã(0x0080)ãèšå®ãããŠããå Žåã ãã§ãã
m - ãªãã¬ã¯ããããã¡ãœããspecialCaller - ã¡ãœããã圢åŒäžåŒã³åºãã¯ã©ã¹IllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããããèšå®ãããŠããŠasVarargsCollectorã倱æããå ŽåNullPointerException - ããããã®åŒæ°ãnullã®å Žåpublic MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException
newInstanceæäœãå®è¡ããã¡ãœããã»ãã³ãã«ã«æž¡ãããåŒæ°ã«åºã¥ããŠã³ã³ã¹ãã©ã¯ã¿ã®ã¯ã©ã¹ã®æ°ããã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã
ã³ã³ã¹ãã©ã¯ã¿ã®accessibleãã©ã°ãèšå®ãããŠããªãå Žåãã«ãã¯ã¢ããã»ã¯ã©ã¹ã«ä»£ãã£ãŠå³åº§ã«ã¢ã¯ã»ã¹ã»ãã§ãã¯ãå®è¡ãããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã®åŒæ°ãå¯å€åŒæ°ã«ãªãã®ã¯ãã³ã³ã¹ãã©ã¯ã¿ã®å¯å€åŒæ°ä¿®é£Ÿåããã(0x0080)ãèšå®ãããŠããå Žåã ãã§ãã
è¿ãããã¡ãœããã»ãã³ãã«ãåŒã³åºãããå Žåããã®ã³ã³ã¹ãã©ã¯ã¿ã®ã¯ã©ã¹ã¯åæåãããŸã(ãŸã åæåãããŠããªãå Žå)ã
c - ãªãã¬ã¯ããããã³ã³ã¹ãã©ã¯ã¿IllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåããŸãã¯ã¡ãœããã®å¯å€åŒæ°ä¿®é£Ÿåããããèšå®ãããŠããŠasVarargsCollectorã倱æããå ŽåNullPointerException - åŒæ°ãnullã®å Žåpublic MethodHandle unreflectGetter(Field f) throws IllegalAccessException
accessibleãã©ã°ãèšå®ãããŠããªãå Žåãã«ãã¯ã¢ããã»ã¯ã©ã¹ã«ä»£ãã£ãŠå³åº§ã«ã¢ã¯ã»ã¹ã»ãã§ãã¯ãå®è¡ãããŸãã
ãã£ãŒã«ããstaticã§ãè¿ãããã¡ãœããã»ãã³ãã«ãåŒã³åºãããå Žåããã®ãã£ãŒã«ãã®ã¯ã©ã¹ã¯åæåãããŸã(ãŸã åæåãããŠããªãå Žå)ã
f - ãªãã¬ã¯ãããããã£ãŒã«ãIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåNullPointerException - åŒæ°ãnullã®å Žåpublic MethodHandle unreflectSetter(Field f) throws IllegalAccessException
accessibleãã©ã°ãèšå®ãããŠããªãå Žåãã«ãã¯ã¢ããã»ã¯ã©ã¹ã«ä»£ãã£ãŠå³åº§ã«ã¢ã¯ã»ã¹ã»ãã§ãã¯ãå®è¡ãããŸãã
ãã£ãŒã«ããstaticã§ãè¿ãããã¡ãœããã»ãã³ãã«ãåŒã³åºãããå Žåããã®ãã£ãŒã«ãã®ã¯ã©ã¹ã¯åæåãããŸã(ãŸã åæåãããŠããªãå Žå)ã
f - ãªãã¬ã¯ãããããã£ãŒã«ãIllegalAccessException - ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåNullPointerException - åŒæ°ãnullã®å Žåpublic MethodHandleInfo revealDirect(MethodHandle target)
target - ã·ã³ããªãã¯åç
§ã³ã³ããŒãã³ãã«è§£æ±ºããçŽæ¥ã¡ãœããã»ãã³ãã«SecurityException - ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšãããããã¢ã¯ã»ã¹ãæåŠããå ŽåIllegalArgumentException - ã¿ãŒã²ãããçŽæ¥ã¡ãœããã»ãã³ãã«ã§ãªãå ŽåããŸãã¯ã¢ã¯ã»ã¹ã»ãã§ãã¯ã倱æããå ŽåNullPointerException - ã¿ãŒã²ãããnullã®å ŽåMethodHandleInfo ãã°ãŸãã¯æ©èœãéä¿¡
詳现ãªAPIãªãã¡ã¬ã³ã¹ããã³éçºè
ããã¥ã¡ã³ãã«ã€ããŠã¯ãJava SEã®ããã¥ã¡ã³ããåç
§ããŠãã ããã ãã®ããã¥ã¡ã³ãã«ã¯ãæŠå¿µçãªæŠèŠãçšèªã®å®çŸ©ãåé¿æ¹æ³ãæå¹ãªã³ãŒãäŸãªã©ã®ãéçºè
ã察象ã«ãããã詳现ãªèª¬æãå«ãŸããŠããŸãã
Copyright © 1993, 2025, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Documentation Redistribution Policyãåç
§ããŠãã ããã