내 프레임 워크에는 다음과 같은 클래스가 있습니다.
public class Foo<B, V> {
private final Method getterMethod;
...
public V executeGetter(B bean) {
try {
return getterMethod.invoke(bean);
} catch ...
}
}
이 클래스는 내 프레임 워크의 컴파일 타임에 사용할 수없는 사용자가 만든 클래스의 getter를 호출하는 데 사용됩니다. 예를 B
들어라는 클래스가 될 수 있습니다 Person
.
프로파일 링을 통해이 방법이 매우 느리다는 것을 발견했습니다. 은 Method.invoke()
(심지어 프로파일로 샘플의 성능의 40 %를 얻어 setAccessible(true)
비 반사 구현하는 성능의 작은 부분을 취하면서).
그래서 교체하고 싶습니다 MethodHandle
.
public class Foo<B, V> {
private final MethodHandle getterMethodHandle;
...
public V executeGetter(B bean) {
try {
return getterMethodHandle.invoke(bean);
} catch ...
}
}
하지만 다음 예외가 발생합니다.
java.lang.ClassCastException: Cannot cast [Ljava.lang.Object; to Person
at sun.invoke.util.ValueConversions.newClassCastException(ValueConversions.java:461)
at sun.invoke.util.ValueConversions.castReference(ValueConversions.java:456)
at ...Foo.executeGetter(Foo.java:123)
bean
의 인스턴스 이지만 Person
. 이제 오해 부분은이 캐스팅하려고한다는 것입니다 Object[]
(아닌 Object
)에 Person
. 개체 배열로 래핑하면 (성능 손실) 도움이되지 않습니다.
return getterMethodHandle.invoke(new Object[]{bean}); // Same exception
그것은 얻을 수 있습니다 MethodHandle
이러한 상황에서 작업을?
그건 ClassCastException
당신이 소스 / 목표 수준 자바 6 컴파일하는 경우에만 발생합니다.
이를 방지하려면 소스 / 타겟 레벨 7 이상으로 컴파일하십시오ClassCastException
.
Tagir의 답변 덕분에 답변을 찾았습니다. (그의 대답도 투표하십시오)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다