2012-05-16 3 views
2

이것은 매우 좋지 않습니다.하지만 코드 작성자 이외의 다른 사람이 사용하는 모든 종류의 코드에이 코드를 넣으려고하지 않습니다. 코드 작성자가 테스트하는 경우를 제외하고는 호출 할 수 없습니다.주위를 둘러보기 유형 체크

내가 직면 한 문제는 다음과 같습니다. 외부에 정의 된 일련의 클래스가 있습니다. 어떤 식 으로든 그들을 수정할 수는 없습니다 (물론 하위 클래스 나 호출 할 수있는 것을 제외하고). 그것들은 다양한 이름을 가지고 있지만 어떤 슈퍼 클래스 (Object 제외)를 확장하지 않거나 인터페이스를 구현하지 않습니다. 그러나 내가 그들 각각에 대해 알고있는 것은 그들이 '전화'라는 방법을 가지고 있다는 것입니다.

테스트를 위해이 클래스의 호출 메서드 중 하나를 호출 할 코드를 작성하려고합니다. 그러나 물론 Object.call()은 모든 객체에 대해 호출이 정의되어 있지 않기 때문에 말할 수 없습니다.

MyClassOne classOne = new MyClassOne(); 
MyClassOneInput classOneInput = new MyclassOneInput(); 

classOne.call(classOneInput); 

을하지만이되지 않습니다 : 기본적으로

이 작동합니다

Object clazz = getClassFromElsewhere(); 
Object clazzInput = getClassInputFromElsewhere(); 

clazz.call(clazzInput). 

물론, 자바는 강력한 형식의 언어이기 때문이다.

그러나이 시스템에서 일하는 모든 사람에 대해 10 배 빠른 테스트를 위해 어떻게 든 어떻게 돌아 다니고 어떻게 든 클래스와 ClassInput에 대해 '호출'메서드를 사용할 수 있습니까? 잘못된 클래스가 전달되면 예외가 발생하거나 완전히 중단되면 아무런 문제가 없습니다.

개체 오리 엔테이션을 위반하는 데 도움을주십시오. 발견하는 경우

+9

[리플렉션] (http://docs.oracle.com/javase/tutorial/reflect/index.html)에 대해 알고 있습니까? –

+0

소리가 비슷합니다. C# 4 이상에서 [동적] (http://msdn.microsoft.com/en-us/library/dd264736.aspx) 키워드와 유사한 기능을 찾고 있습니다. Java와 같은 것은 존재하지 않습니다. –

+0

You 리플렉션을 사용하여 클래스에 정의 된 메소드 목록을 가져올 수 있습니다. 'call()'에 대한 목록을 검색하고 찾으면이를 호출 할 수 있습니다.이게 좋은 생각인지는 모르겠지만 더 나빴습니다. –

답변

8

리플렉션을 사용하면이 작업을 수행 할 수 있습니다.

MyClassOne classOne = new MyClassOne(); 
MyClassOneInput classOneInput = new MyClassOneInput(); 
Method m = classOne.getClass().getMethod("call", MyClassOneInput.class); 
m.invoke(classOne, classOneInput); 

참고 : 다음은 reflection API

을 확인 하는 것은 간단한 예입니다 당신은 개인 및 보호 포함한 모든 방법을 얻을 수 getDeclaredMethod를 사용할 수 있지만 당신은 m "를 호출해야합니다.

+2

+1은'm.setAccessible (true)'에 중요합니다. – Hoons

3

사용 Reflection

  1. getClass()
  2. getMethod()
  3. 객체에 호출 사용하여 "전화"방법을 찾아 사용하여 클래스를 얻을

예를 들어,

java.lang.reflect.Method method; 
try { 
    method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..); 
} catch (SecurityException e) { 
    // ... 
} catch (NoSuchMethodException e) { 
    // ... 
} 

그런 다음

try { 
    method.invoke(obj, arg1, arg2,...); 
} catch (IllegalArgumentException e) { 
} catch (IllegalAccessException e) { 
} catch (InvocationTargetException e) { 

How do I invoke a Java method when given the method name as a string?

나는 또한 더 적은 "나쁜 OO"를 보일 수 있습니다 다음과 같은 일을하는 동적 JVM 언어 (JRuby를, 자이 썬, 그루비)에보고 고려할 참조 더 자연스러운 느낌을줍니다.

6

Java Reflection에 적합합니다. 이것은 의사 코드 예제이지만 다음과 같습니다.

Object obj = getExternalObject(); 
Method meth = obj.getClass().getDeclaredMethod("call"); 
meth.invoke(obj); 
+0

나는 반사를 소개하려하고 있었다. .. 멋진! :-) –