getter と setterを持つ単純な javabeanMyPerson
があるとします。name
public class MyPerson {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
今、私は単にそのname
フィールドを取得して設定するこのメイン コードを実行しています。
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle getterMethodHandle = lookup.findGetter(MyPerson.class, "name", String.class);
MethodHandle setterMethodHandle = lookup.findSetter(MyPerson.class, "name", String.class);
MyPerson a = new MyPerson();
a.setName("Batman");
System.out.println("Name from getterMethodHandle: " + getterMethodHandle.invoke(a));
setterMethodHandle.invoke(a, "Robin");
System.out.println("Name after setterMethodHandle: " + a.getName());
}
そのmain()
メソッドを classに追加するとMyPerson
、期待どおりの結果が得られます。
Name from getterMethodHandle: Batman
Name after setterMethodHandle: Robin
別のパッケージの別のクラスに同じmain()
メソッドを追加すると、次の奇妙なエラーが発生します。
Exception in thread "main" java.lang.NoSuchFieldException: no such field: batman.other.MyMain.name/java.lang.String/getField
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:875)
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:990)
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1373)
at java.lang.invoke.MethodHandles$Lookup.findGetter(MethodHandles.java:1022)
at batman.other.MyMain.main(MyMain.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.NoSuchFieldError: name
at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:962)
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:987)
なんで?の getter/setter は public であるため、MethodHandles を介しても使用しないMyPerson
理由はありません。MyMain
ソース/ターゲット レベルの Java 8 で JDK 8 を使用する。