나는 스칼라 REPL을 사용하여 빠른 자바 반복과 테스트를하기 위해 정기적으로 사용하지만 때로는 클래스의 일부 비공개 동작을 트리거하고 메서드를 볼 수 있도록 코드를 다시 컴파일해야한다. 코드를 변경할 필요없이 REPL에서 직접 개인 Java 메소드를 호출 할 수 있기를 원합니다.스칼라에서 private Java 메소드 호출하기
지금까지있어 무엇 :
처럼 사용할 수 있습니다// Calls private Java methods
// We currently define an overload for every n-argument method
// there's probably a way to do this in one method?
def callPrivate(obj: AnyRef, methodName: String) = {
val method = obj.getClass().getDeclaredMethod(methodName)
val returnType = method.getReturnType
method.setAccessible(true)
println("Call .asInstanceOf[%s] to cast" format method.getReturnType.getName)
method.getReturnType.cast(method.invoke(obj))
}
def callPrivate(obj: AnyRef, methodName: String, arg: AnyRef) = {
val method = obj.getClass().getDeclaredMethod(methodName, arg.getClass())
method.setAccessible(true)
method.invoke(obj, arg)
}
:
scala> callPrivate(myObj, "privateMethod", arg).asInstanceOf[ReturnedClass]
그러나 이것은 매 n 인수 방식 유형에 대한 근처 중복 방법을 정의해야합니다 (그리고 필요 외부 출연자,하지만 피할 수없는 것 같아요). 한 함수가 여러 개의 인수를 처리 할 수 있도록이 함수를 리펙토링하는 방법이 있습니까?
참고 : 저는 Java Reflection을 사용하는 솔루션을 찾고 있으므로 Scala 2.9.1을 사용하고 있습니다. Scala Reflection을 사용한 답변은 환영하지만 직접 문제를 해결하지는 못합니다.
정말 고마워. 그게 내가 필요한 포인터 였어. 나는'method.getReturnType.cast() '를 호출하면'java.lang.Object' 대신에'Any'를 반환합니다.) 그러나 varargs의 동작은 이제 작동합니다. 내가 컴파일 한 나의 현재 구현으로 당신의 대답을 업데이트 할 자유를 얻었다. 당신이 원한다면 별도의 답변으로 게시 할 수 있습니다. – dimo414
개선의 여지가 여전히 있습니다. 제네릭을 사용하면 형식 유추의 이점을 제대로 누리고 클라이언트에서의 캐스팅을 피할 수 있습니다. 아마도 당신은'callPrivateTyped [T] (...) : T'와 같은 메서드를 선언 할 필요가 있고 반환하기 전에'method.invoke (obj, parameterValues : _ *). asInstanceOf (T)'를 할 수 있습니다. 'var result : SomeType = callPrivateTyped (....)'(또는'var result = callPrivateTyped [SomeType] (....)')을 호출하도록 호출자를 변경할 수 있습니다. 제네릭은 테스트하지 않고 작성하는 까다로운 일이기 때문에 제 대답. – Claudio