public class MethodHandles extends Object
| 修食åãšå | ã¯ã©ã¹ | 説æ |
|---|---|---|
static class |
MethodHandles.Lookup |
ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã¯ãã¡ãœããã»ãã³ãã«ã®äœæã«ã¢ã¯ã»ã¹ã»ãã§ãã¯ãå¿
èŠãªå Žåã®ã¡ãœããã»ãã³ãã«äœæçšãã¡ã¯ããªã§ãã
|
| 修食åãšå | ã¡ãœãã | 説æ |
|---|---|---|
static MethodHandle |
arrayElementGetter(Class<?> arrayClass) |
é
åã®åèŠçŽ ã«å¯Ÿããèªåãã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
arrayElementSetter(Class<?> arrayClass) |
é
åã®åèŠçŽ ã«å¯ŸããæžèŸŒã¿ã¢ã¯ã»ã¹ãæäŸããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
catchException(MethodHandle target, Class<? extends Throwable> exType, MethodHandle handler) |
ã¿ãŒã²ããã®ã¡ãœããã»ãã³ãã«ãäŸå€ãã³ãã©ã®å
éšã§å®è¡ããããšã«ãã£ãŠããã®ã¿ãŒã²ãããé©å¿ãããã¡ãœããã»ãã³ãã«ãäœæããŸãã
|
static MethodHandle |
collectArguments(MethodHandle target, int pos, MethodHandle filter) |
ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ãããã£ã«ã¿(å¥ã®ã¡ãœããã»ãã³ãã«)ã§ãã®åŒæ°ã®ãµãã·ãŒã±ã³ã¹ãååŠçããããšã«ãããé©å¿ãããŸãã
|
static MethodHandle |
constant(Class<?> type, Object value) |
èŠæ±ãããæ»ãå€ã®åãæã¡ãåŒã³åºããããã³ã«æå®ããã宿°å€ãè¿ãã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) |
ããã€ãã®ãããŒåŒæ°ãç Žæ£ããŠããæå®ãããå¥ã®targetã¡ãœããã»ãã³ãã«ãåŒã³åºãã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) |
ããã€ãã®ãããŒåŒæ°ãç Žæ£ããŠããæå®ãããå¥ã®targetã¡ãœããã»ãã³ãã«ãåŒã³åºãã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
exactInvoker(MethodType type) |
ç¹æ®ãªã€ã³ããŒã«ã»ã¡ãœããã»ãã³ãã«ãçæããŸã(ããã䜿çšããã°ãæå®ãããåã®ä»»æã®ã¡ãœããã»ãã³ãã«ãã
invokeExactã䜿çšããå Žåãšåæ§ã«åŒã³åºãããšãã§ãã)ã |
static MethodHandle |
explicitCastArguments(MethodHandle target, MethodType newType) |
æå®ãããã¡ãœããã»ãã³ãã«ã®åãæ°ããåã«é©å¿ãããããã«ãåŒæ°ãšæ»ãå€ã®åã®å€æããã¢åäœã§è¡ãã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
filterArguments(MethodHandle target, int pos, MethodHandle... filters) |
ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ãé©å¿ãããããããã®1ã€ä»¥äžã®åŒæ°ãããããåºæã®åé
ãã£ã«ã¿é¢æ°ã䜿ã£ãŠååŠçããããšãååŠçãè¡ã£ãååŒæ°ã察å¿ãããã£ã«ã¿é¢æ°ã®çµæã§çœ®ãæããŠã¿ãŒã²ãããåŒã³åºããŸãã
|
static MethodHandle |
filterReturnValue(MethodHandle target, MethodHandle filter) |
ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ãé©å¿ãããããããã®æ»ãå€(ååšããå Žå)ããã£ã«ã¿(å¥ã®ã¡ãœããã»ãã³ãã«)ã§åŸåŠçããŸãã
|
static MethodHandle |
foldArguments(MethodHandle target, MethodHandle combiner) |
ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ãé©å¿ãããããããã®åŒæ°ã®ããã€ããååŠçããããšãååŠçã®çµæãå
ã®äžé£ã®åŒæ°å
ã«æ¿å
¥ããŠã¿ãŒã²ãããåŒã³åºããŸãã
|
static MethodHandle |
guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback) |
ãã¹ã(booleanå€ã®ã¡ãœããã»ãã³ãã«)ã§ä¿è·ããããšã§ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ãé©å¿ãããã¡ãœããã»ãã³ãã«ãäœæããŸãã
|
static MethodHandle |
identity(Class<?> type) |
åŒåºãæã«å¯äžã®åŒæ°ã®å€ãè¿ãã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandle |
insertArguments(MethodHandle target, int pos, Object... values) |
ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ã®åŒåºãã®åã«ã1ã€ä»¥äžã®ãã€ã³ãåŒæ°ãã¡ãœããã»ãã³ãã«ã«æäŸããŸãã
|
static MethodHandle |
invoker(MethodType type) |
ç¹æ®ãªã€ã³ããŒã«ã»ã¡ãœããã»ãã³ãã«ãçæããŸã(ããã䜿çšããã°ãæå®ãããåãšäºææ§ã®ããä»»æã®ã¡ãœããã»ãã³ãã«ãã
invokeã䜿çšããå Žåãšåæ§ã«åŒã³åºãããšãã§ãã)ã |
static MethodHandles.Lookup |
lookup() |
åŒåºãå
ã®ãã¹ãŠã®ãµããŒãããããã€ãã³ãŒãåäœããšãã¥ã¬ãŒãããããã®ãã«æ©èœãæã€
ã«ãã¯ã¢ããã»ãªããžã§ã¯ããè¿ããŸãã |
static MethodHandle |
permuteArguments(MethodHandle target, MethodType newType, int... reorder) |
åŒæ°ã®é åºã倿Žããããšã«ãã£ãŠãæå®ãããã¡ãœããã»ãã³ãã«ã®åŒåºãé åºãæ°ããåã«é©å¿ãããã¡ãœããã»ãã³ãã«ãçæããŸãã
|
static MethodHandles.Lookup |
publicLookup() |
æå°ã®ä¿¡é Œã¬ãã«ãæã€
ã«ãã¯ã¢ããã»ãªããžã§ã¯ããè¿ããŸãã |
static <T extends Member> |
reflectAs(Class<T> expected, MethodHandle target) |
çŽæ¥ã¡ãœããã»ãã³ãã«ã®æªãã§ãã¯ã®è§£èªãå®è¡ããŸãã
|
static MethodHandle |
spreadInvoker(MethodType type, int leadingArgCount) |
æå®ããã
typeã®ä»»æã®ã¡ãœããã»ãã³ãã«ãåŒã³åºãã¡ãœããã»ãã³ãã«ãçæããŸããããã®éãæå®ãããæ°ã®æ«å°Ÿã®åŒæ°ãåäžã®æ«å°Ÿã®Object[]é
åã§çœ®ãæããããŸãã |
static MethodHandle |
throwException(Class<?> returnType, Class<? extends Throwable> exType) |
æå®ããã
exTypeã®äŸå€ãã¹ããŒããã¡ãœããã»ãã³ãã«ãçæããŸãã |
public static MethodHandles.Lookup lookup()
ã«ãã¯ã¢ããã»ãªããžã§ã¯ããè¿ããŸãã ãããã®æ©èœã«ã¯åŒåºãå
ãžã®privateã¢ã¯ã»ã¹ãå«ãŸããŸãã ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã®ãã¡ã¯ããªã»ã¡ãœããã¯ãåŒåºãå
ããã€ãã³ãŒããä»ããŠã¢ã¯ã»ã¹ããã¡ã³ããŒ(protectedããã³privateã®ãã£ãŒã«ãããã³ã¡ãœãããå«ã)ã®çŽæ¥ã¡ãœããã»ãã³ãã«ãäœæã§ããŸãã ãã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã¯ãä¿¡é Œã§ãããšãŒãžã§ã³ãã«å§è²å¯èœãª1ã€ã®æ©èœã§ãã ä¿¡é Œã§ããªãã³ãŒãããã¢ã¯ã»ã¹å¯èœãªå Žæã«æ ŒçŽããªãã§ãã ããã
ãã®ã¡ãœããã¯åŒåºãå äŸåã§ããã€ãŸããåŒåºãå ããšã«ç°ãªãå€ãè¿ãå¯èœæ§ããããŸãã
åŒåºãå
ã¯ã©ã¹Cãæå®ãããå Žåããã®åŒåºãã«ãã£ãŠè¿ãããã«ãã¯ã¢ããã»ãªããžã§ã¯ãã¯ãåãåŒåºãå
ã¯ã©ã¹Cã§å®è¡ããinvokedynamicåœä»€ã®ããŒãã¹ãã©ããã»ã¡ãœããã«å¯ŸããŠJVMã«ãã£ãŠæäŸãããã«ãã¯ã¢ããã»ãªããžã§ã¯ããšåçã®æ©èœãæã¡ãŸãã
public static MethodHandles.Lookup publicLookup()
ã«ãã¯ã¢ããã»ãªããžã§ã¯ããè¿ããŸãã ããã¯ãpublicã®ã¢ã¯ã»ã¹å¯èœãªãã£ãŒã«ããã¡ãœãããžã®ã¡ãœããã»ãã³ãã«ãäœæããå Žåã«ã®ã¿äœ¿çšã§ããŸãã
åã«æ
£äŸã«ããããã®ã«ãã¯ã¢ããã»ãªããžã§ã¯ãã®ã«ãã¯ã¢ããã»ã¯ã©ã¹ã¯ãObjectã«ãªããŸãã
ãã£ã¹ã«ãã·ã§ã³: ã«ãã¯ã¢ããã»ã¯ã©ã¹ã¯ãpublicLookup().in(C.class)圢åŒã®åŒã䜿çšããŠãä»ã®ä»»æã®ã¯ã©ã¹Cã«å€æŽã§ããŸãã publicã®ååã«å¯Ÿããã¢ã¯ã»ã¹ã¯ã©ã®ã¯ã©ã¹ããã¹ãŠåãã§ããããããã®ãããªå€æŽã«ãã£ãŠæ°ããã¢ã¯ã»ã¹æš©ãä»äžãããããšã¯ãããŸããã publicã«ãã¯ã¢ããã»ãªããžã§ã¯ãã¯åžžã«ã»ãã¥ãªãã£ã»ãããŒãžã£ã»ãã§ãã¯ãé©çšãããŸãã ãŸããåŒåºãå
äŸåã¡ãœããã«ã¢ã¯ã»ã¹ããããšãã§ããŸããã
public static <T extends Member> T reflectAs(Class<T> expected, MethodHandle target)
Lookup.revealDirectãåŒã³åºããŠã·ã³ããªãã¯åç
§ãååŸããMethodHandleInfo.reflectAsãåŒã³åºããŠã·ã³ããªãã¯åç
§ãã¡ã³ããŒã«è§£æ±ºãããã®ããã«ãªããŸãã
ã»ãã¥ãªãã£ã»ãããŒãžã£ãååšããå Žåã¯ããã®checkPermissionã¡ãœãããReflectPermission("suppressAccessChecks")ã¢ã¯ã»ã¹æš©ã§åŒã³åºãããŸãã
T - çµæã«æåŸ
ããå(MemberãŸãã¯ãµãã¿ã€ã)target - ã·ã³ããªãã¯åç
§ã³ã³ããŒãã³ãã«è§£æ±ºããçŽæ¥ã¡ãœããã»ãã³ãã«expected - æåŸ
ããçµæåTã衚ãã¯ã©ã¹ã»ãªããžã§ã¯ãSecurityException - åŒåºãå
ã«setAccessibleãåŒã³åºãæš©éãäžããããŠããªãå ŽåNullPointerException - ã©ã¡ããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - ã¿ãŒã²ãããçŽæ¥ã¡ãœããã»ãã³ãã«ã§ãªãå ŽåClassCastException - ã¡ã³ããŒãæåŸ
ãããåã§ãªãå Žåpublic static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException
intã«ãªããŸãã arrayClass - é
åã®åNullPointerException - åŒæ°ãnullã®å ŽåIllegalArgumentException - arrayClassãé
ååã§ãªãå Žåpublic static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException
arrayClass - é
åã®ã¯ã©ã¹NullPointerException - åŒæ°ãnullã®å ŽåIllegalArgumentException - arrayClassãé
ååã§ãªãå Žåpublic static MethodHandle spreadInvoker(MethodType type, int leadingArgCount)
typeã®ä»»æã®ã¡ãœããã»ãã³ãã«ãåŒã³åºãã¡ãœããã»ãã³ãã«ãçæããŸããããã®éãæå®ãããæ°ã®æ«å°Ÿã®åŒæ°ãåäžã®æ«å°Ÿã®Object[]é
åã§çœ®ãæããããŸãã çµæãšãªãã€ã³ããŒã«ã¯ã次ã®åŒæ°ãæã€ã¡ãœããã»ãã³ãã«ã§ãã
MethodHandleã¿ãŒã²ãã
leadingArgCount)
Object[]é
å
ã€ã³ããŒã«ããã®ã¿ãŒã²ãããåŒã³åºãæ¹æ³ã¯ã瀺ãããtypeã䜿çšããinvokeã®åŒåºãã«äŒŒãŠããŸãã ã€ãŸããã®åäœã¯ãã¿ãŒã²ããã®åãæå®ãããtypeãšå®å
šã«çããå Žåã¯invokeExactã®ããã«ãªãããã以å€ã®å Žåã¯ãasTypeã䜿ã£ãŠã¿ãŒã²ãããå¿
èŠãªtypeã«å€æãããããªåäœã«ãªããŸãã
è¿ãããã€ã³ããŒã«ã®åã¯ãæå®ãããtypeã§ã¯ãªããæåã®leadingArgCountåãé€ããã¹ãŠã®ãã©ã¡ãŒã¿ãåäžã®Object[]åé
åã§çœ®ãæãããããã®ãšãªãããããæåŸã®ãã©ã¡ãŒã¿ã«ãªããŸãã
ã€ã³ããŒã«ã¯ãã®ã¿ãŒã²ãããåŒã³åºãåã«ãæåŸã®é
åãåé
ããåç
§ãã£ã¹ããå¿
èŠã«å¿ããŠé©çšããã»ããããªããã£ãåŒæ°ã®ã¢ã³ãã¯ã·ã³ã°ãã¯ã€ããã³ã°ãè¡ããŸãã ã€ã³ããŒã«ãåŒã³åºããããšãã«ãæž¡ãããé
ååŒæ°ãæ£ããæ°ã®èŠçŽ ãæããªãå Žåãã€ã³ããŒã«ã¯ã¿ãŒã²ãããåŒã³åºããããã«IllegalArgumentExceptionãã¹ããŒããŸãã
ãã®ã¡ãœããã¯æ¬¡ã®ã³ãŒããšåçã§ã(ãã ããå¹çã¯ãããããã®ã¡ãœããã®ã»ããé«ã)ã
ãã®ã¡ãœããã§ã¯ããªãã¬ã¯ã·ã§ã³ãã»ãã¥ãªãã£ã«é¢ããäŸå€ã¯ã¹ããŒãããŸãããMethodHandle invoker = MethodHandles.invoker(type); int spreadArgCount = type.parameterCount() - leadingArgCount; invoker = invoker.asSpreader(Object[].class, spreadArgCount); return invoker;
type - ç®çãšãªãã¿ãŒã²ããã®åleadingArgCount - ã¿ãŒã²ããã«ç¡å€æŽã§æž¡ãããåºå®åŒæ°ã®æ°NullPointerException - typeãnullã§ããå ŽåIllegalArgumentException - leadingArgCountã0ããtype.parameterCount()(å«ã)ãŸã§ã®ç¯å²ã§ãªãå ŽåããŸãã¯çµæã®ã¡ãœããã»ãã³ãã«ã®åã®ãã©ã¡ãŒã¿æ°ãå€ãããå Žåpublic static MethodHandle exactInvoker(MethodType type)
invokeExactã䜿çšããå Žåãšåæ§ã«åŒã³åºãããšãã§ãã)ã çµæãšãªãã€ã³ããŒã«ã®åã¯ãMethodHandleåã®è¿œå ã®å
é ã®åŒæ°ã1ã€åãåãç¹ãé€ãã°ãç®çã®åãšãŸã£ããçãããªããŸãã
ãã®ã¡ãœããã¯æ¬¡ã®ã³ãŒããšåçã§ã(ãã ããå¹çã¯ãããããã®ã¡ãœããã®ã»ããé«ã)ã publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
解説: ã€ã³ããŒã«ã»ã¡ãœããã»ãã³ãã«ã¯ãæªç¥ã®åã®ã¡ãœããã»ãã³ãã«å€æ°ãæäœããå Žåã«åœ¹ç«ã€å¯èœæ§ããããŸãã ããšãã°ãã¡ãœããã»ãã³ãã«å€æ°Mãžã®invokeExactåŒåºãããšãã¥ã¬ãŒãããã«ã¯ããã®åTãæœåºããTçšã®ã€ã³ããŒã«ã»ã¡ãœããXãæ€çŽ¢ããã€ã³ããŒã«ã»ã¡ãœãããX.invoke(T, A...)ã®ããã«åŒã³åºããŸãã (åTãæªç¥ã§ãããããX.invokeExactã®åŒåºãã¯æ©èœããªãã) åé
ãåéãªã©ã®åŒæ°å€æãå¿
èŠãªå Žåã¯ãããããã€ã³ããŒã«Xã«äžåºŠã ãé©çšããŠããã°ãMã®ããŸããŸãªã¡ãœããã»ãã³ãã«å€(ãã ãXã®åãšäºææ§ããããã®ã«ããã)ã§åå©çšã§ããŸãã
(ããŒã: Core Reflection APIçµç±ã§ã€ã³ããŒã«ã»ã¡ãœããã䜿çšããããšã¯ã§ããŸããã 宣èšãããinvokeExactãŸãã¯invokeã¡ãœããã§java.lang.reflect.Method.invokeãåŒã³åºãããšãããšãUnsupportedOperationExceptionãçºè¡ãããŸãã)
ãã®ã¡ãœããã§ã¯ããªãã¬ã¯ã·ã§ã³ãã»ãã¥ãªãã£ã«é¢ããäŸå€ã¯ã¹ããŒãããŸããã
type - ç®çãšãªãã¿ãŒã²ããã®åIllegalArgumentException - çµæã®ã¡ãœããã»ãã³ãã«ã®åã®ãã©ã¡ãŒã¿æ°ãå€ãããå Žåpublic static MethodHandle invoker(MethodType type)
invokeã䜿çšããå Žåãšåæ§ã«åŒã³åºãããšãã§ãã)ã çµæãšãªãã€ã³ããŒã«ã®åã¯ãMethodHandleåã®è¿œå ã®å
é ã®åŒæ°ã1ã€åãåãç¹ãé€ãã°ãç®çã®åãšãŸã£ããçãããªããŸãã
ã¿ãŒã²ãããæåŸ
ãããåãšç°ãªã£ãŠããå Žåãã€ã³ããŒã«ã¯ãã®ã¿ãŒã²ãããåŒã³åºãåã«ãasTypeã®å Žåãšåãããã«ãåç
§ãã£ã¹ããå¿
èŠã«å¿ããŠé©çšããã»ããããªããã£ãå€ã®ãã¯ã·ã³ã°ãã¢ã³ãã¯ã·ã³ã°ããŸãã¯ã¯ã€ããã³ã°ãè¡ããŸãã åæ§ã«ãæ»ãå€ãå¿
èŠã«å¿ããŠå€æãããŸãã ã¿ãŒã²ãããå¯å€åŒæ°ã¡ãœããã»ãã³ãã«ã®å Žåã¯ããã¯ãasTypeã®å Žåãšåãããã«ãå¿
èŠãªåŒæ°å€æãè¡ãããŸãã
ãã®ã¡ãœããã¯æ¬¡ã®ã³ãŒããšåçã§ã(ãã ããå¹çã¯ãããããã®ã¡ãœããã®ã»ããé«ã)ã publicLookup().findVirtual(MethodHandle.class, "invoke", type)
ãã£ã¹ã«ãã·ã§ã³: äžè¬çãªã¡ãœããåã¯ãObjectåŒæ°ããã³æ»ãå€ã®ã¿ãèšåãããã®ã§ãã ãã®ãããªåã®ã€ã³ããŒã«ã¯ãåŒæ°ã®æ°ãæ±çšåãšåãã¡ãœããã»ãã³ãã«ã§ããã°ä»»æã®ãã®ãåŒã³åºãããšãã§ããŸãã
(ããŒã: Core Reflection APIçµç±ã§ã€ã³ããŒã«ã»ã¡ãœããã䜿çšããããšã¯ã§ããŸããã 宣èšãããinvokeExactãŸãã¯invokeã¡ãœããã§java.lang.reflect.Method.invokeãåŒã³åºãããšãããšãUnsupportedOperationExceptionãçºè¡ãããŸãã)
ãã®ã¡ãœããã§ã¯ããªãã¬ã¯ã·ã§ã³ãã»ãã¥ãªãã£ã«é¢ããäŸå€ã¯ã¹ããŒãããŸããã
type - ç®çãšãªãã¿ãŒã²ããã®åIllegalArgumentException - çµæã®ã¡ãœããã»ãã³ãã«ã®åã®ãã©ã¡ãŒã¿æ°ãå€ãããå Žåpublic static MethodHandle explicitCastArguments(MethodHandle target, MethodType newType)
å ã®åãšæ°ããåãçããå Žåã¯ã¿ãŒã²ãããè¿ããŸãã
MethodHandle.asTypeã®å Žåãšåã倿ãèš±å¯ãããã»ãããããã®å€æã倱æããå Žåã«ã¯ãããã€ãã®è¿œå ã®å€æãé©çšãããŸãã asTypeã§è¡ããã倿ã®åã«ããããã¯ãã®ä»£ããã«ã次ã®ããããã®å€æãå¯èœã§ããã°é©çšãããŸã(T0ãT1ã¯å)ã
(x & 1)!= 0ãšåæ§ã«è¡ãããŸãã
target - åŒæ°ã®åã調æŽããããšã«åŒã³åºãã¡ãœããã»ãã³ãã«newType - æ°ããã¡ãœããã»ãã³ãã«ã®æåŸ
ãããåNullPointerException - ã©ã¡ããã®åŒæ°ãnullã®å ŽåWrongMethodTypeException - 倿ã§ããªãå ŽåMethodHandle.asType(java.lang.invoke.MethodType)public static MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder)
æå®ãããé
åã«ãã£ãŠäžŠã¹æ¿ããå¶åŸ¡ãããŸãã å
¥åãã©ã¡ãŒã¿ã®æ°(å€newType.parameterCount())ã#Iãåºåãã©ã¡ãŒã¿ã®æ°(å€target.type().parameterCount())ã#OãšããŸãã ãã®ãšããäžŠã¹æ¿ãé
åã®é·ãã¯#OãåèŠçŽ ã¯#Iããå°ããè² ã§ãªãæ°ã§ãªããã°ãããŸããã #Oããå°ãããã¹ãŠã®Nã«ã€ããŠãNçªç®ã®åºååŒæ°ã¯Içªç®ã®å
¥ååŒæ°ããåãããŸã(Iã¯reorder[N])ã
åŒæ°ãæ»ãå€ã®å€æã¯äžåé©çšãããŸããã åå
¥ååŒæ°ã®å(newTypeã«ãã£ãŠæ±ºå®ããã)ã¯ãã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ã®å¯Ÿå¿ãã1ã€ãŸãã¯è€æ°ã®åºåãã©ã¡ãŒã¿ã®åãšåäžã§ãªããã°ãããŸããã newTypeã®æ»ãå€ã®åã¯ãå
ã®ã¿ãŒã²ããã®æ»ãå€ã®åãšåäžã§ãªããã°ãããŸããã
äžŠã¹æ¿ãé
åã§ã¯ãå®éã®å
¥ãæ¿ããæå®ããå¿
èŠã¯ãããŸããã é
åå
ã§ã€ã³ããã¯ã¹ãè€æ°åçŸããå
¥ååŒæ°ã¯è€è£œãããé
åå
ã§ã€ã³ããã¯ã¹ãçŸããªãå
¥ååŒæ°ã¯é€å»ãããŸãã dropArgumentsã®å Žåãšåæ§ã«ãäžŠã¹æ¿ãé
åå
ã§èšåãããŠããªãå
¥ååŒæ°ã¯ã©ã®ãããªåã§ãããŸããŸãã(newTypeã«ãã£ãŠã®ã¿æ±ºå®ããã)ã
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodType intfn1 = methodType(int.class, int.class); MethodType intfn2 = methodType(int.class, int.class, int.class); MethodHandle sub = ... (int x, int y) -> (x-y) ...; assert(sub.type().equals(intfn2)); MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1); MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0); assert((int)rsub.invokeExact(1, 100) == 99); MethodHandle add = ... (int x, int y) -> (x+y) ...; assert(add.type().equals(intfn2)); MethodHandle twice = permuteArguments(add, intfn1, 0, 0); assert(twice.type().equals(intfn1)); assert((int)twice.invokeExact(21) == 42);
target - åŒæ°ãäžŠã¹æ¿ããããšã§åŒã³åºãã¡ãœããã»ãã³ãã«newType - æ°ããã¡ãœããã»ãã³ãã«ã®æåŸ
ãããåreorder - äžŠã¹æ¿ããå¶åŸ¡ããã€ã³ããã¯ã¹é
åNullPointerException - ããããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - ã€ã³ããã¯ã¹é
åã®é·ããã¿ãŒã²ããã®åŒæ°é·ãšçãããªãå ŽåããŸãã¯ã€ã³ããã¯ã¹é
åã«ãnewTypeã®ãã©ã¡ãŒã¿ã®æå¹ãªã€ã³ããã¯ã¹ã§ãªãèŠçŽ ãå«ãŸããŠããå ŽåããŸãã¯target.type()ãšnewTypeã®å¯Ÿå¿ãã2ã€ã®ãã©ã¡ãŒã¿ã®åãåäžã§ãªãå Žåpublic static MethodHandle constant(Class<?> type, Object value)
ã¡ãœããã»ãã³ãã«ãè¿ãããåã«ãæž¡ãããå€ãèŠæ±ãããåã«å€æãããŸãã èŠæ±ãããåãããªããã£ãã®å Žåã¯ããªããã£ãã»ã¯ã€ããã³ã°å€æã詊ã¿ããããã以å€ã®å Žåã¯åç §å€æã詊ã¿ãããŸãã
è¿ãããã¡ãœããã»ãã³ãã«ã¯identity(type).bindTo(value)ãšåçã§ãã
type - å¿
èŠãªã¡ãœããã»ãã³ãã«ã®æ»ãå€ã®åvalue - è¿ãå€NullPointerException - typeåŒæ°ãnullã®å ŽåClassCastException - èŠæ±ãããæ»ãå€ã®åã«å€ã倿ã§ããªãå ŽåIllegalArgumentException - æå®ãããåãvoid.classã®å Žåpublic static MethodHandle identity(Class<?> type)
type - å¿
èŠãªã¡ãœããã»ãã³ãã«ã®å¯äžã®ãã©ã¡ãŒã¿ãšæ»ãå€ã®åNullPointerException - åŒæ°ãnullã®å ŽåIllegalArgumentException - æå®ãããåãvoid.classã®å Žåpublic static MethodHandle insertArguments(MethodHandle target, int pos, Object... values)
æ°ããã¡ãœããã»ãã³ãã«ã®åã«ã¯ãå ã®ã¿ãŒã²ããã®åã«å«ãŸããŠãããã€ã³ãã»ãã©ã¡ãŒã¿ã®åã¯å«ãŸããŸããããããã¯ãæ°ããã¡ãœããã»ãã³ãã«ã§ã¯ãããåŒåºãå ããããã®åŒæ°ãæå®ããå¿ èŠããªãããã§ãã
æå®ãããåŒæ°ã®ãªããžã§ã¯ãã¯ããããã察å¿ãããã€ã³ãã»ãã©ã¡ãŒã¿ã®åã«äžèŽããå¿ èŠããããŸãã ãã€ã³ãã»ãã©ã¡ãŒã¿ã®åãããªããã£ãã®å ŽåãåŒæ°ã®ãªããžã§ã¯ãã¯ã©ãããŒã§ããå¿ èŠãããããªããžã§ã¯ããã¢ã³ãã¯ã·ã³ã°ãããŠããªããã£ãå€ãçæãããŸãã
posåŒæ°ã«ãã£ãŠãã€ã³ããããã©ã¡ãŒã¿ãéžæãããŸãã ãã®ç¯å²ã¯0 - N-L (䞡端ãå«ã)ã§ããããã§ãNã¯ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ã®åŒæ°é·ãLã¯å€é
åã®é·ãã§ãã
target - åŒæ°ãæ¿å
¥ããããšã«åŒã³åºãã¡ãœããã»ãã³ãã«pos - åŒæ°ã®æ¿å
¥äœçœ®(å
é ã®å Žåã¯ãŒã)values - æ¿å
¥ããäžé£ã®åŒæ°NullPointerException - ã¿ãŒã²ãããŸãã¯valuesé
åãnullã®å ŽåMethodHandle.bindTo(java.lang.Object)public static MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes)
posåŒæ°ã®ç¯å²ã¯0 - N (Nã¯ã¿ãŒã²ããã®åŒæ°ã®æ°)ã«ãªããŸãã ãããŒåŒæ°ã¯ãposã0ã®å Žåã¯ã¿ãŒã²ããã®å®éã®åŒæ°ã®åã«è¿œå ãããposãNã®å Žåã¯åŸãã«è¿œå ãããŸãã
äŸ:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class); MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2)); assertEquals(bigType, d0.type()); assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
ãã®ã¡ãœããã¯æ¬¡ã®ã³ãŒããšãåçã§ãã
dropArguments(target, pos, valueTypes.toArray(new Class[0]))
target - åŒæ°ãé€å»ããããšã«åŒã³åºãã¡ãœããã»ãã³ãã«valueTypes - é€å»ããåŒæ°ã®åpos - é€å»ããæåã®åŒæ°ã®äœçœ®(巊端ã®å Žåã¯0)NullPointerException - ã¿ãŒã²ãããnullã®å ŽåããŸãã¯valueTypesãªã¹ããŸãã¯ãã®ããããã®èŠçŽ ãnullã®å ŽåIllegalArgumentException - valueTypesã®ããããã®èŠçŽ ãvoid.classã®å ŽåããŸãã¯posãè² ã§ãããã¿ãŒã²ããã®åŒæ°ã®æ°ãã倧ããå ŽåããŸãã¯æ°ããã¡ãœããã»ãã³ãã«ã®åã«å«ãŸãããã©ã¡ãŒã¿ã®æ°ãå€ãããå Žåpublic static MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes)
posåŒæ°ã®ç¯å²ã¯0 - N (Nã¯ã¿ãŒã²ããã®åŒæ°ã®æ°)ã«ãªããŸãã ãããŒåŒæ°ã¯ãposã0ã®å Žåã¯ã¿ãŒã²ããã®å®éã®åŒæ°ã®åã«è¿œå ãããposãNã®å Žåã¯åŸãã«è¿œå ãããŸãã
äŸ:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodHandle d0 = dropArguments(cat, 0, String.class); assertEquals("yz", (String) d0.invokeExact("x", "y", "z")); MethodHandle d1 = dropArguments(cat, 1, String.class); assertEquals("xz", (String) d1.invokeExact("x", "y", "z")); MethodHandle d2 = dropArguments(cat, 2, String.class); assertEquals("xy", (String) d2.invokeExact("x", "y", "z")); MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class); assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
ãã®ã¡ãœããã¯æ¬¡ã®ã³ãŒããšãåçã§ãã
dropArguments(target, pos, Arrays.asList(valueTypes))
target - åŒæ°ãé€å»ããããšã«åŒã³åºãã¡ãœããã»ãã³ãã«valueTypes - é€å»ããåŒæ°ã®åpos - é€å»ããæåã®åŒæ°ã®äœçœ®(巊端ã®å Žåã¯0)NullPointerException - ã¿ãŒã²ãããnullã®å ŽåããŸãã¯valueTypesé
åãŸãã¯ãã®ããããã®èŠçŽ ãnullã®å ŽåIllegalArgumentException - valueTypesã®ããããã®èŠçŽ ãvoid.classã®å ŽåããŸãã¯posãè² ãŸãã¯ã¿ãŒã²ããã®åŒæ°ã«ãŠã³ããã倧ããå ŽåããŸãã¯æ°ããã¡ãœããã»ãã³ãã«ã®åã®ãã©ã¡ãŒã¿æ°ãå€ãããå Žåpublic static MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters)
ååŠçã¯ãfiltersé
åã®èŠçŽ ãšããŠæå®ããã1ã€ä»¥äžã®ã¡ãœããã»ãã³ãã«ã«ãã£ãŠå®è¡ãããŸãã ãã£ã«ã¿é
åã®æåã®èŠçŽ ãã¿ãŒã²ããã®posã®äœçœ®ã®åŒæ°ã«å¯Ÿå¿ããããšãã£ãé¢ä¿ããã®åŸãé ã«ç¶ããŸãã
é åå ã®nullåŒæ°ã¯ã¢ã€ãã³ãã£ãã£é¢æ°ãšã¿ãªããã察å¿ããåŒæ°ã¯å€æŽãããªããŸãŸã«ãªããŸãã (nullã§ãªãèŠçŽ ãé åå ã«1ã€ãååšããªãå Žåã¯ãå ã®ã¿ãŒã²ãããè¿ãããŸãã) åãã£ã«ã¿ã¯ã¢ããã¿ã®å¯Ÿå¿ããåŒæ°ã«é©çšãããŸãã
ãã£ã«ã¿Fãã¿ãŒã²ããã®Nçªç®ã®åŒæ°ã«é©çšãããå ŽåãFã¯ãã¡ããã©1ã€ã®åŒæ°ãåãã¡ãœããã»ãã³ãã«ã§ãªããã°ãããŸããã çµæãšãªãé©å¿åŸã®ã¡ãœããã»ãã³ãã«å
ã§ã¯ãFã®å¯äžã®åŒæ°ã®åã§ãã¿ãŒã²ããã®å¯Ÿå¿ããåŒæ°ã®åã眮ãæããããŸãã Fã®æ»ãå€ã®åã¯ãã¿ãŒã²ããã®å¯Ÿå¿ãããã©ã¡ãŒã¿ã®åãšåäžã§ãªããã°ãããŸããã
ã¿ãŒã²ããå
ã®åŒæ°äœçœ®ã«å¯Ÿå¿ããªãfiltersã®èŠçŽ (nullã®å Žåããã)ãååšããå Žåã¯ããšã©ãŒã«ãªããŸãã
äŸ:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodHandle upcase = lookup().findVirtual(String.class, "toUpperCase", methodType(String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodHandle f0 = filterArguments(cat, 0, upcase); assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy MethodHandle f1 = filterArguments(cat, 1, upcase); assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY MethodHandle f2 = filterArguments(cat, 0, upcase, upcase); assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
çµæãšãªãã¢ããã¿ã®æ¬äŒŒã³ãŒããæ¬¡ã«ç€ºããŸãã
V target(P... p, A[i]... a[i], B... b); A[i] filter[i](V[i]); T adapter(P... p, V[i]... v[i], B... b) { return target(p..., f[i](v[i])..., b...); }
target - åŒæ°ããã£ã«ã¿ãªã³ã°ããããšã§åŒã³åºãã¡ãœããã»ãã³ãã«pos - ãã£ã«ã¿ãªã³ã°ããæåã®åŒæ°ã®äœçœ®filters - ãã£ã«ã¿ãªã³ã°å¯Ÿè±¡ã®åŒæ°ã«å¯ŸããŠæåã«åŒã³åºãã¡ãœããã»ãã³ãã«NullPointerException - ã¿ãŒã²ãããnullã®å ŽåãŸãã¯filtersé
åãnullã®å ŽåIllegalArgumentException - filtersã®énullèŠçŽ ãã¿ãŒã²ããã®å¯Ÿå¿ããåŒæ°åãšäžèŽããªãå Žå(åè¿°ã®èª¬æãåç
§)ããŸãã¯pos+filters.lengthãtarget.type().parameterCount()ãã倧ããå ŽåããŸãã¯çµæã®ã¡ãœããã»ãã³ãã«ã®åã®ãã©ã¡ãŒã¿æ°ãå€ãããå Žåpublic static MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter)
ãã£ã«ã¿ãå€ãè¿ãå Žåãã¿ãŒã²ããã¯ãã®å€ãäœçœ®pos(ãã£ã«ã¿ã«æž¡ãããªãåŒæ°ã®åãŸãã¯åŸ)ã®åŒæ°ãšããŠåãå
¥ããå¿
èŠããããŸãã ãã£ã«ã¿ãvoidãè¿ãå Žåãã¿ãŒã²ããã¯ãã£ã«ã¿ã«æž¡ãããªããã¹ãŠã®åŒæ°ãåãå
¥ããå¿
èŠããããŸãã åŒæ°ã¯äžŠã¹æ¿ããããããã£ã«ã¿ããè¿ãããçµæã«ãã£ãŠã¢ããã¿ã«ããšããšæž¡ãããåŒæ°ãµãã·ãŒã±ã³ã¹å
šäœã(é çªã«)眮ãæããããŸãã
ãã£ã«ã¿ã®åŒæ°å(ããå Žå)ã¯ãçµæã®é©å¿æžã¡ãœããã»ãã³ãã«å
ã§ãã¿ãŒã²ããã®0ãŸãã¯1åã®åŒæ°å(äœçœ®pos)ã眮ãæããŸãã ãã£ã«ã¿ã®æ»ãå(ããå Žå)ã¯ãã¿ãŒã²ããã®äœçœ®posã®åŒæ°åãšåãã§ããå¿
èŠãããããã®ã¿ãŒã²ããåŒæ°ã¯ãã£ã«ã¿ã®æ»ãå€ã«ãã£ãŠæäŸãããŸãã
ã©ã®ãããªå Žåã§ããposã¯0以äžã§ããå¿
èŠããããposã¯ã¿ãŒã²ããã®åŒæ°ã«ãŠã³ã以äžã§ããå¿
èŠããããŸãã
äŸ:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle deepToString = publicLookup() .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class)); MethodHandle ts1 = deepToString.asCollector(String[].class, 1); assertEquals("[strange]", (String) ts1.invokeExact("strange")); MethodHandle ts2 = deepToString.asCollector(String[].class, 2); assertEquals("[up, down]", (String) ts2.invokeExact("up", "down")); MethodHandle ts3 = deepToString.asCollector(String[].class, 3); MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2); assertEquals("[top, [up, down], strange]", (String) ts3_ts2.invokeExact("top", "up", "down", "strange")); MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1); assertEquals("[top, [up, down], [strange]]", (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange")); MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3); assertEquals("[top, [[up, down, strange], charm], bottom]", (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
çµæãšãªãã¢ããã¿ã®æ¬äŒŒã³ãŒããæ¬¡ã«ç€ºããŸãã
T target(A...,V,C...); V filter(B...); T adapter(A... a,B... b,C... c) { V v = filter(b...); return target(a...,v,c...); } // and if the filter has no arguments: T target2(A...,V,C...); V filter2(); T adapter2(A... a,C... c) { V v = filter2(); return target2(a...,v,c...); } // and if the filter has a void return: T target3(A...,C...); void filter3(B...); void adapter3(A... a,B... b,C... c) { filter3(b...); return target3(a...,c...); }
ã³ã¬ã¯ã·ã§ã³ã»ã¢ããã¿collectArguments(mh, 0, coll)ã¯ã次ã®ãããªåå¥ã®ã¹ãããã§ããŸã圱é¿ãåããåŒæ°ãæããããã§ãã(fold)ç Žæ£(drop)ãããã®ãšåçã§ãã
ã¿ãŒã²ããã»ã¡ãœããã»ãã³ãã«ããã£ã«ã¿mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2 mh = MethodHandles.foldArguments(mh, coll); //step 1
collã®çµæ(ããå Žå)以å€ã«åŒæ°ãæ¶è²»ããªãå Žåã¯ãcollectArguments(mh, 0, coll)ã¯filterReturnValue(coll, mh)ãšåçã§ãã ãã£ã«ã¿ã»ã¡ãœããã»ãã³ãã«collã1ã€ã®åŒæ°ãæ¶è²»ããŠévoidçµæãçæããå Žåã¯ãcollectArguments(mh, N, coll)ã¯filterArguments(mh, N, coll)ãšåçã§ãã ä»ã®ç䟡æ§ãå¯èœã§ãããåŒæ°é åãå¿
èŠã§ãã target - åŒæ°ãµãã·ãŒã±ã³ã¹ããã£ã«ã¿ããåŸã«åŒã³åºãã¡ãœããã»ãã³ãã«pos - ãã£ã«ã¿ã«æž¡ãæåã®ã¢ããã¿åŒæ°ããŸãã¯ãã£ã«ã¿ã®çµæãåãåãã¿ãŒã²ããåŒæ°ããããã¯ãã®äž¡æ¹ã®äœçœ®filter - åŒæ°ãµãã·ãŒã±ã³ã¹ã§åŒã³åºãã¡ãœããã»ãã³ãã«NullPointerException - ã©ã¡ããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - filterã®æ»ãåãévoidã§ã¿ãŒã²ããã®posåŒæ°ãšåãã§ãªãå ŽåããŸãã¯posã0ããã¿ãŒã²ããã®åŒæ°ã«ãŠã³ãã®é(å«ã)ã«ãªãå ŽåããŸãã¯çµæã®ã¡ãœããã»ãã³ãã«ã®åã®ãã©ã¡ãŒã¿æ°ãå€ãããå ŽåfoldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)ãfilterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...)ãfilterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)public static MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter)
ã¿ãŒã²ãããå€ãè¿ãå Žåããã£ã«ã¿ã¯ãã®å€ãå¯äžã®åŒæ°ãšããŠåãå ¥ããå¿ èŠããããŸãã ã¿ãŒã²ãããvoidãè¿ãå Žåããã£ã«ã¿ã¯åŒæ°ãäžååãå ¥ããŠã¯ãããŸããã
çµæãšãªãé©å¿åŸã®ã¡ãœããã»ãã³ãã«å ã§ã¯ããã£ã«ã¿ã®æ»ãå€ã®åã§ã¿ãŒã²ããã®æ»ãå€ã®åã眮ãæããããŸãã ãã£ã«ã¿ã®åŒæ°ã®å(ååšããå Žå)ã¯ãã¿ãŒã²ããã®æ»ãå€ã®åãšåäžã§ãªããã°ãããŸããã
äŸ:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodHandle length = lookup().findVirtual(String.class, "length", methodType(int.class)); System.out.println((String) cat.invokeExact("x", "y")); // xy MethodHandle f0 = filterReturnValue(cat, length); System.out.println((int) f0.invokeExact("x", "y")); // 2
çµæãšãªãã¢ããã¿ã®æ¬äŒŒã³ãŒããæ¬¡ã«ç€ºããŸãã
V target(A...); T filter(V); T adapter(A... a) { V v = target(a...); return filter(v); } // and if the target has a void return: void target2(A...); T filter2(); T adapter2(A... a) { target2(a...); return filter2(); } // and if the filter has a void return: V target3(A...); void filter3(V); void adapter3(A... a) { V v = target3(a...); filter3(v); }
target - æ»ãå€ããã£ã«ã¿ãªã³ã°ããåã«åŒã³åºãã¡ãœããã»ãã³ãã«filter - æ»ãå€ã«å¯ŸããŠåŒã³åºãã¡ãœããã»ãã³ãã«NullPointerException - ã©ã¡ããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - åè¿°ã®ããã«filterã®åŒæ°ãªã¹ããã¿ãŒã²ããã®æ»ãå€ã®åãšäžèŽããªãå Žåpublic static MethodHandle foldArguments(MethodHandle target, MethodHandle combiner)
ååŠçã¯ã2çªç®ã®ã¡ãœããã»ãã³ãã«ã§ããcombinerã«ãã£ãŠå®è¡ãããŸãã ã¢ããã¿ã«æž¡ãããåŒæ°ã®ãã¡ãæåã®Nåã®åŒæ°ãã³ã³ãã€ãã«ã³ããŒãããããšãã³ã³ãã€ããåŒã³åºãããŸãã (ããã§ãNã¯ã³ã³ãã€ãã®ãã©ã¡ãŒã¿æ°ãšããŠå®çŸ©ãããã) ãã®ããšå¶åŸ¡ãã¿ãŒã²ããã«æž¡ãããŸããããã®éãã³ã³ãã€ãã®ãã¹ãŠã®çµæãå
ã®Nåã®å
¥ååŒæ°ã®åã«æ¿å
¥ãããŸãã
ã³ã³ãã€ããå€ãè¿ãå Žåãã¿ãŒã²ããã®æåã®ãã©ã¡ãŒã¿ã®åãã³ã³ãã€ãã®æ»ãå€ã®åãšåäžã§ããå¿
èŠãããã»ããã¿ãŒã²ããã®æ¬¡ã®Nåã®ãã©ã¡ãŒã¿ã®åãã³ã³ãã€ãã®ãã©ã¡ãŒã¿ãšå³å¯ã«äžèŽããŠããå¿
èŠããããŸãã
ã³ã³ãã€ãã®æ»ãå€ãvoidã®å Žåãçµæã¯äžåæ¿å
¥ãããªãã®ã§ãã¿ãŒã²ããã®æåã®Nåã®ãã©ã¡ãŒã¿ã®åãã³ã³ãã€ãã®ãã©ã¡ãŒã¿ãšå³å¯ã«äžèŽããå¿
èŠããããŸãã
çµæãšãªãã¢ããã¿ã®åã¯ã¿ãŒã²ãããšã»ãŒåãã«ãªããŸãããæåã®ãã©ã¡ãŒã¿ã®åãã³ã³ãã€ãã®çµæã«å¯Ÿå¿ããŠããå Žåã¯ãã®åã¯é€å»ãããç¹ãç°ãªããŸãã
(dropArgumentsã䜿ãã°ãã³ã³ãã€ããŸãã¯ã¿ãŒã²ãããåãåãå¿
èŠã®ãªãåŒæ°ããã¹ãŠåé€ã§ããŸãã å
¥ååŒæ°ã®äžéšãã³ã³ãã€ãå°çšã®å Žåããããã®åŒæ°ã¯ã¿ãŒã²ãããžã®ãšã³ããªæã«ã¹ã¿ãã¯äžã«ååšããŠããå¿
èŠããªããããasCollectorã代ããã«äœ¿çšããããšãæ€èšããŠãã ããã)
äŸ:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class, "println", methodType(void.class, String.class)) .bindTo(System.out); MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("boojum", (String) cat.invokeExact("boo", "jum")); MethodHandle catTrace = foldArguments(cat, trace); // also prints "boo": assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
çµæãšãªãã¢ããã¿ã®æ¬äŒŒã³ãŒããæ¬¡ã«ç€ºããŸãã
// there are N arguments in A... T target(V, A[N]..., B...); V combiner(A...); T adapter(A... a, B... b) { V v = combiner(a...); return target(v, a..., b...); } // and if the combiner has a void return: T target2(A[N]..., B...); void combiner2(A...); T adapter2(A... a, B... b) { combiner2(a...); return target2(a..., b...); }
target - åŒæ°ãçµåããããšã§åŒã³åºãã¡ãœããã»ãã³ãã«combiner - å
¥ååŒæ°ã«å¯ŸããŠæåã«åŒã³åºãã¡ãœããã»ãã³ãã«NullPointerException - ã©ã¡ããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - combinerã®æ»ãå€ã®åãvoidã§ãªããã¿ãŒã²ããã®æåã®åŒæ°ã®åãšåãã§ãªãå Žåããããã¯ã¿ãŒã²ããã®æåã®Nåã®åŒæ°ã®å(combinerã®æ»ãå€ã®åã«äžèŽããåã¯é€ã)ãcombinerã®åŒæ°ã®åãšåäžã§ãªãå Žåpublic static MethodHandle guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback)
çµæãšãªãã¢ããã¿ã®æ¬äŒŒã³ãŒããæ¬¡ã«ç€ºããŸãã
ãã¹ãã®åŒæ°(æ¬äŒŒã³ãŒãã§ã¯boolean test(A...); T target(A...,B...); T fallback(A...,B...); T adapter(A... a,B... b) { if (test(a...)) return target(a..., b...); else return fallback(a..., b...); }
a...)ã¯ããã¹ãã®å®è¡æã«å€æŽãããå¯èœæ§ã¯ãªãã®ã§ãåŒåºãå
ããå¿
èŠã«å¿ããŠã¿ãŒã²ãããŸãã¯ãã©ãŒã«ã»ããã¯ã«ãã®ãŸãŸæž¡ãããŸããtest - ãã¹ãã«äœ¿çšãããã¡ãœããã»ãã³ãã«ã§booleanãè¿ãå¿
èŠãããtarget - ãã¹ãã«ãã¹ããå Žåã«åŒã³åºãã¡ãœããã»ãã³ãã«fallback - ãã¹ãã«å€±æããå Žåã«åŒã³åºãã¡ãœããã»ãã³ãã«NullPointerException - ããããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - testãbooleanãè¿ããªãå ŽåããŸãã¯(testã®æ»ãå€ã®åã倿ŽããŠã¿ãŒã²ããã®åãšäžèŽãããŠã) 3ã€ã®ãã¹ãŠã®ã¡ãœããåãäžèŽããªãå Žåpublic static MethodHandle catchException(MethodHandle target, Class<? extends Throwable> exType, MethodHandle handler)
ã¿ãŒã²ãããšãã³ãã©ã®å¯Ÿå¿ããåŒæ°ãšæ»ãå€ã®åã¯åºæ¬çã«åãã§ããå¿
èŠããããŸããããã³ãã©ã§ã¯(guardWithTestã®è¿°èªãšåæ§ã«)æ«å°Ÿã®è€æ°ã®åŒæ°ãçç¥ã§ããŸãã ããã«ãã³ãã©ã¯ãexTypeãŸãã¯ã¹ãŒããŒã»ã¿ã€ãã®å
é ã®ãã©ã¡ãŒã¿ã远å ã§1ã€æã€å¿
èŠããããŸãã
çµæãšãªãã¢ããã¿ã®æ¬äŒŒã³ãŒããæ¬¡ã«ç€ºããŸãã
ä¿åãããåŒæ°(æ¬äŒŒã³ãŒãã§ã¯T target(A..., B...); T handler(ExType, A...); T adapter(A... a, B... b) { try { return target(a..., b...); } catch (ExType ex) { return handler(ex, a...); } }
a...)ã¯ãã¿ãŒã²ããã®å®è¡æã«å€æŽãããå¯èœæ§ã¯ãªãã®ã§ããã³ãã©ãåŒã³åºãããå Žåã«ã¯åŒåºãå
ãããã³ãã©ã«ãã®ãŸãŸæž¡ãããŸãã
ãã³ãã©ãåžžã«ã¹ããŒããå Žåã§ããã¿ãŒã²ãããšãã³ãã©ã®æ»ãå€ã®åã¯åãã§ãªããã°ãããŸããã (ããã¯ãããšãã°ãã³ãã©ãfinallyç¯ãã·ãã¥ã¬ãŒãããŠããããã«çºçããå¯èœæ§ããããŸã)ã ãã®ãããªã¹ããŒãããã³ãã©ãäœæããã«ã¯ãthrowExceptionã䜿ã£ãŠãã³ãã©äœæããžãã¯ãæ§ç¯ããæ£ããæ»ãå€ã®åãæã€ã¡ãœããã»ãã³ãã«ãäœæãããããã«ããŸãã
target - åŒã³åºãã¡ãœããã»ãã³ãã«exType - ãã³ãã©ããã£ããããäŸå€ã®åhandler - äžèŽããäŸå€ãã¹ããŒãããå Žåã«åŒã³åºãã¡ãœããã»ãã³ãã«NullPointerException - ããããã®åŒæ°ãnullã®å ŽåIllegalArgumentException - handlerãæå®ãããäŸå€ã®åãåãå
¥ããªãå ŽåããŸãã¯ã¡ãœããã»ãã³ãã«ã®åã«å«ãŸããæ»ãå€ã®åãšå¯Ÿå¿ãããã©ã¡ãŒã¿ãäžèŽããªãå Žåpublic static MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType)
exTypeã®äŸå€ãã¹ããŒããã¡ãœããã»ãã³ãã«ãçæããŸãã ã¡ãœããã»ãã³ãã«ã¯ãexTypeã®åäžã®åŒæ°ãåãå
¥ããããã峿ã«äŸå€ãšããŠã¹ããŒããŸãã ã¡ãœããåã§ã¯åœ¢åŒäžãreturnTypeã®æ»ãå€ãæå®ãããŸãã æ»ãå€ã®åã¯ãã©ã®ãããªãã®ã§ãããŸããŸãããã¡ãœããã»ãã³ãã«ãéåžžã©ããã«æ»ãããšã¯æ±ºããŠãªãã®ã§ãã¡ãœããã»ãã³ãã«ã®åäœã«ã¯äœã®åœ±é¿ããããŸããã returnType - æåŸ
ããã¡ãœããã»ãã³ãã«ã®æ»ãåexType - æåŸ
ããã¡ãœããã»ãã³ãã«ã®ãã©ã¡ãŒã¿åNullPointerException - ã©ã¡ããã®åŒæ°ãnullã®å Žå ãã°ãŸãã¯æ©èœãéä¿¡
詳现ãªAPIãªãã¡ã¬ã³ã¹ããã³éçºè
ããã¥ã¡ã³ãã«ã€ããŠã¯ãJava SEã®ããã¥ã¡ã³ããåç
§ããŠãã ããã ãã®ããã¥ã¡ã³ãã«ã¯ãæŠå¿µçãªæŠèŠãçšèªã®å®çŸ©ãåé¿æ¹æ³ãæå¹ãªã³ãŒãäŸãªã©ã®ãéçºè
ã察象ã«ãããã詳现ãªèª¬æãå«ãŸããŠããŸãã
Copyright © 1993, 2025, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Documentation Redistribution Policyãåç
§ããŠãã ããã