2010-01-06 5 views
7

개체 메서드에 대한 참조를 얻을 수 있습니까? 예를 들어, 다른 메서드를 콜백으로 호출하는 메서드를 갖고 싶습니다. 다음과 같이 입력하십시오 :Java 메소드에 대한 참조를 나중에 호출 할 수 있습니까?

public class Whatever 
{ 
    public void myMethod(Method m,Object args[]) 
    { 

    } 
} 

이게 가능합니까?

편집 : 개체의 메서드를 의미합니다. 나는 그것을 가져갈 수 없다고 생각하니?

+0

"개체의 메서드"가 아니라 "클래스의 메서드"를 의미합니까? – skaffman

+0

@skaffman : 객체의 클래스 메쏘드. 어떻게에 대한? 이는 중요한 구분입니다. 익명의 클래스 인스턴스가있는 경우 인스턴스에서 클래스에 대해 'getClass'를 호출해야만 클래스를 참조 할 수 있습니다. 리플렉션을 사용하면 일반적으로 기본 인터페이스 인/class/enum을 통해 액세스 할 수없는 다른 방법에 액세스 할 수 있습니다. :-P –

답변

6

예, 가능합니다.

방금 ​​메소드를 가져 와서 호출하십시오.

$cat InvokeMethod.java 
import java.lang.reflect.Method; 
import java.lang.reflect.InvocationTargetException; 

public class InvokeMethod { 

    public static void invokeMethod(Method m , Object o , Object ... args) 
    throws IllegalAccessException, 
      InvocationTargetException { 

     m.invoke(o, args); 

    } 

    public static void main(String [] args) 
    throws NoSuchMethodException, 
      IllegalAccessException, 
      InvocationTargetException { 

     SomeObject object = new SomeObject(); 
     Method method = object.getClass().getDeclaredMethod("someMethod", String.class); 
     invokeMethod(method, object, "World"); 

    } 
} 

class SomeObject { 
    public void someMethod(String name){ 
     System.out.println(" Hello " + name); 
    } 
} 
$javac InvokeMethod.java 
$java InvokeMethod 
Hello World 
$ 

이제 질문은, 당신이해야 할 노력하고있다 :

여기에 몇 가지 예제 코드는? 아마도 더 나은 방법 일 것입니다. 그러나 귀하의 질문에 대한 답변은 예입니다.

4

Java 7에는 이것을 수행 할 수있는 클로저가 있습니다. 이 사용할 수있을 때까지

은 두 가지 옵션이

  • 에 공지 된 방법과 인터페이스에 대한 참조를 잡고
  • 사용 반사 메서드를 호출하는 것을 전화가 있습니다.
+1

Java 7에는 메서드 핸들도 있으며,이 핸들은 훨씬 더 직접적입니다. :-P –

+0

C# 스타일 대리자는 어떻게됩니까? 우리는 언제든지 그것을 얻고 있습니까? –

+0

클로저가 Java 7을 통해 만들었습니까? – OscarRyz

1

예, java.lang.Class.getMethods()과 같은 리플렉션 API를 사용합니다 (Class에서 다른 유사한 방법). Method.invoke()을 사용하여 Method 개체를 호출합니다.

리플렉션 API는 사용하기가 특히 좋지 않으며 성능상의 불이익을 지닙니다 (예전보다 훨씬 덜 중요하지만).

3

Java의 디자인 철학과 상반되게 실행됩니다. 단일 메소드 클래스를 작성하고 그 인스턴스에 대한 참조를 전달해야합니다.

+0

우리가 클래스의 세터에 대해 말하면 스케일되지 않습니다. 10 setter + 10 getter = typesafe 방식으로 그들을 참조하는 20 개의 객체는 좋지 않습니다. ^^ 따라서 형식이 다른 문자열과 반사 (많은 프레임 워크 에서처럼)로 끝납니다. – Tarion

+0

나는 그것이 좋은 것임을 말하는 것이 아닙니다. 대리자와 함께 C#으로 이동하십시오! –

3

여기 콜백에 필요한 있는지의 예 :

public interface Callback { 
    public void execute(Object[] args); 
} 

public class MyCallback implements Callback { 
    public void execute(Object args[]) { 
    System.out.println(Arrays.asList(args)); 
    } 
} 

public class Whatever { 
    public void myMethod(Callback callback,Object args[]) { 
    callback.execute(args); 
    } 
} 

당신이 Whatever.myMethod에 MyCallback의 인스턴스를 넘겨 경우에, 당신은 인수로 손에 무엇이든 인쇄됩니다. 반사 통해

0

당신이 클래스의 메소드에 액세스 할 수 있습니다 - 그러나

http://java.sun.com/docs/books/tutorial/reflect/member/methodInvocation.html

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Method.html

를 참조하면 해당 클래스의 인스턴스를 전달뿐만 아니라해야 인수들. 그래도 간단한 래퍼 클래스를 만들 수 있습니다.

class MethodInvoker{ 
     private Object o; 
     private String methodName; 
     public MethodInvoker(Object o, String methodName){ 
      this.o=o; 
      this.methodName=methodName; 
     } 

     public Object invoke(Object[] args) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{ 
      Class[] paramTypes = new Class[args.length]; 
      for(int i=0;i<paramTypes.length;i++){ 
       paramTypes[i] = args[i].getClass(); 
      } 
      return o.getClass().getMethod(methodName, paramTypes).invoke(o, args); 
     } 
    } 

null 매개 변수에는 사용할 수 없으므로주의해야합니다.

1

리플렉션을 통해 가능하지만 훨씬 더 나은 방법은 객체를 전달하고 현재 정렬 작업 (비교 자 전달)과 같은 방식으로 인터페이스를 통해 액세스하는 것입니다. 생각과 습관을 습득하는 것은 실제로 OO 프로그래밍을 이해하는 시작입니다.

메소드 참조를 통해 전반적인 디자인이 악화됩니다. 그러나 일회용 해킹 작업이 쉬워지는 것은 분명합니다. 해킹에 만족한다면 Groovy를 사용하십시오. 대신 모든 지름길이 내장되어 있으며 장기간 유지 관리 대신 빠른 일회용 코드를 위해 설계된 단순화 된 구문이 많이 줄어 듭니다.

관련 문제