2013-04-08 4 views
4

Eclipse RCP 애플리케이션을 개발 중이며 최근에 Groovy를 사용하기 시작했습니다. 그래서 내 코드의 99 %는 여전히 Java입니다.자바 클래스가 내 코드에서 인스턴스화되지 않은 경우 Groovy를 사용하여 Java 클래스의 메소드를 대체 할 수 있습니까?

Groovy를 사용하여 Java 클래스에 메소드를 대체하고 추가 할 수 있다는 것을 읽었으며 java.lang.String에 메소드를 추가하여이를 테스트 할 수있었습니다.

그러나 이것은 Groovy 클래스에서 문자열을 사용할 때만 작동합니다. 재정의 된 메서드는 Java 클래스에서 재정의되는 것으로 간주되지 않습니다.

/* 
* This is a Java class 
*/ 
public class CTabItem { 
    ... 
    private API 
    ... 
    public void setControl(Control control){ 
     private API 
    } 
} 

/* 
* This is also a Java class 
*/ 
public class Control { 
    ... 
    private API 
    ... 
} 

/* 
* This is also a Java class 
*/ 
public class OtherClass { 
    ... 
    private API 
    ... 
    private void someMethodIDontKnow(){ 
    Control control = new Control(); 
    CTabItem tab = new CTabItem(); 
    tab.setControl(control); 
    } 
} 

/* 
* This is a Groovy class 
*/ 
public class MyViewPart extends org.eclipse.ui.part.ViewPart { 
    .... 
    public void createPartControl(Composite parent) { 
      /* parent (or the parent of parent) is a Control 
      which is set somewhere in a CTabItem to which 
      I don't get access */ 
    }   
} 

내가 컨트롤에서 탭을 얻을 필요가 :

는 여기에 몇 가지 코드입니다. 그러나 MyViewPart를 인스턴스화하는 것은 내가 아니기 때문에 일부 개인 API는 액세스 할 수 없습니다. 그루비가 나를 위해 할 수있는 것이 있습니까? 어떤 제안이나 코드도 환영합니다. 고맙습니다!

+0

어떻게 Java로 해결하겠습니까? 리플렉션 사용? – Will

+0

잘 모르겠다. 그루비에서 해결하기를 바랬다. – Alex

답변

10

짧은 대답은 : 아니오, 객체를 생성하고 메소드를 호출하는 코드가 순수 Java (즉, Groovy가 아닌) 코드 인 경우에는 불가능합니다. Groovy는 객체 (Java 객체와 Groovy 객체 모두)에 대한 모든 메소드 호출을 가로 채고 ExpandoMetaClass을 사용하여 동작을 추가함으로써 마술을 수행합니다. 그러나 순수 Java 코드가 순수 Java 클래스에서 호출 할 메소드를 결정하는 방법을 변경할 수는 없습니다. 확인하려면 다음 예제 코드를 실행

// UseTheString.java (a pure Java class) 
public class UseTheString { 
    public static void main(String[] arg) { 
     String s = "Hello world"; 
     System.out.println(s); 
     System.out.println(s.substring(1)); 
     ModifyStringClass.messWithMetaClasses(s); 
     System.out.println(s.substring(1)); 
    } 
} 

// ModifyStringClass.groovy (a Groovy class) 
class ModifyStringClass { 
    public static messWithMetaClasses(String t) { 
     java.lang.String.metaClass.substring = { int n -> "!" } 
     println(t.substring(1)) 
    } 
} 
당신은 출력을 얻을 것이다

:

Hello world 
ello world 
! 
ello world 

당신이 볼 수 있듯이, 그루비가에 메소드를 오버라이드 (override) 할 수 있습니다 순수한 Java 오브젝트가 다른 Groovy 코드에서 호출되었지만 Java 코드가이를 사용하는 방식을 변경할 수는 없습니다.

관련 문제