Đây là phần theo dõi trên Java8 retrieving lambda setter from class.Đảm bảo an toàn loại trên biểu thức lambda chung
Tôi đang cố gắng để có được một phương thức getter cho một lĩnh vực nhất định
public <T, R> IGetter<T, R> getGetter(Class<T> clazz, Field field) {
Class<R> fieldType = null;
try {
fieldType = (Class<R>) field.getType();
} catch(ClassCastException e) {
error("Attempted to create a mistyped getter for the field " + field + "!");
}
return getGetter(clazz, field.getName(), fieldType);
}
Đây là phương pháp cơ bản:
public <T, R> IGetter<T, R> getGetter(Class<T> clazz, String fieldName, Class<R> fieldType) {
MethodHandles.Lookup caller = null;
MethodHandle target = null;
MethodType func = null;
try {
caller = MethodHandles.lookup();
MethodType getter = MethodType.methodType(fieldType);
target = caller.findVirtual(clazz, computeGetterName(fieldName), getter);
func = target.type();
} catch (NoSuchMethodException e) {
error("Could not locate a properly named getter \"" + computeGetterName(fieldName) + "\"!");
} catch (IllegalAccessException e) {
error("Could not access \"" + computeGetterName(fieldName) + "\"!");
}
CallSite site = null;
try {
site = LambdaMetafactory.metafactory(
caller,
"get",
MethodType.methodType(IGetter.class),
func.generic(),
target,
func
);
} catch (LambdaConversionException e) {
error("Could not convert the getter \"" + computeGetterName(fieldName) + "\" into a lambda expression!");
}
MethodHandle factory = site.getTarget();
IGetter<T, R> r = null;
try {
r = (IGetter<T, R>) factory.invoke();
} catch (Throwable throwable) {
error("Casting the factory of \"" + computeGetterName(fieldName) + "\" failed!");
}
return r;
}
này không biên dịch, do một loại không phù hợp:
IGetter<TestEntity, Long> getter = accessorFactory.getGetter(TestEntity.class, "name", String.class);
Điều này tuy nhiên biên dịch:
Field field = TestEntity.class.getDeclaredField("name");
IGetter<TestEntity, Long> getter = accessorFactory.getGetter(TestEntity.class, field);
Và, trước sự ngạc nhiên của tôi, điều này làm việc bằng cách sử dụng phương thức getter được lấy ra ở trên:
TestEntity testEntity = new TestEntity(1L, "Test");
System.out.println(getter.get(testEntity));
Tuy nhiên, một khi tôi làm điều này:
Long value = getter.get(testEntity);
tôi nhận được ngoại lệ sau đây:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at de.cyclonit.exercise.Main.main(Main.java:26)
Có cách nào để nắm bắt điều này sớm hơn không?
Các TestEntity lớp:
public class TestEntity {
private Long id;
private String name;
public TestEntity(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
}