2010-08-23 7 views
7

Java 클래스의 메서드를 다시 구현하고 싶습니다. 예를 들어 "hi".length()4을 반환합니다. (어떻게) 할 수 있을까요?String # 길이를 재정의 할 수 있습니까?

SomeClass.metaClass를 사용하여 알고 있습니다. 기존 메소드에 대한 참조를 가져 와서 새 (또는 재정의) 메소드를 정의 할 수 있지만 기존 Java 메소드에서는이를 수행 할 수없는 것처럼 보입니다.

+0

4를 반환 String.length()을 만드는 방법 요청한 예, 즉이다. 문자열을 주어진 최대 길이까지 확장하는'pad()'메소드를 사용할 수있을 것이다. 그런 다음 해당 문자열에서 길이를 호출 할 수 있습니다. – Nate

+0

그걸로 무엇을하고 싶니? 이런 식으로 많은 코드를 깨뜨릴 수 있습니다. –

+0

왜? 이 일로 얼마나 많은 일들을 깰 수 있습니까? 2 + 2 = 5로 만들 수 있지만 실제로는 최상의 솔루션이 아닐 수도 있습니다. 아마도 몇 가지 특수한 상황에서 반환 된 값을 단순히 조정하고 싶을 것입니다. – mickeyf

답변

2

abusing 문자열 metaClass처럼 가능할 것으로 보입니다. 하지만 지금까지 그루비 콘솔에서했던 시도가 예상 된 결과에지도하지 않았다 :

def oldLength = String.metaClass.length 
String.metaClass.length = { -> 
    return oldLength+10; 
} 

println "hi".length() 

난 당신이 Proxy MetaClass 또는 Delegating metaClass을 살펴 수 있다고 생각 슬픈 2

출력합니다.

+0

나는이 문제와 관련된 문제라고 생각한다 : http://jira.codehaus.org/browse/GROOVY-3493 –

+1

이렇게 보인다 : String.metaClass.invokeMethod = {String methodName, args -> println (" hi ") } "hi ".length() //"안녕하세요 "를 인쇄합니다 – IttayD

+0

저자가 직접 승인 한 경우 실제로이 답변을 수락 한 이유는 무엇입니까? –

1

다시 정의한 경우 Groovy 코드에서만 작동합니다. Groovy는 Java 코드의 실행 방식을 변경할 수 없습니다. 그루비에서

"hi".length()이 자바와 거의 동일합니다 :

stringMetaClass.invokeMethod("hi","length"); 

그루비가 실제로 호출하지 않기 때문에 길이 직접 메타 클래스 트릭은 그루비 코드에서 작동합니다. 그러나 Java는 MetaClass에 대해 알지 못하므로이 방법을 사용할 수 없습니다.

+0

네, 제발 그루비를 위해서만하는 법을 보여주세요. – IttayD

4

Groovy를 사용하면 모든 메소드 (최종 클래스의 메소드 포함)를 사용자 고유의 구현으로 바꿀 수 있습니다. Groovy의 메소드 대체는 상속이 아닌 메타 오브젝트 프로토콜을 사용합니다.

여기에 항상 잘못된 동작 것

// Redefine the method 
String.metaClass.invokeMethod = { name, args -> 

    def metaMethod = delegate.metaClass.getMetaMethod(name, args) 
    def result = metaMethod.invoke(delegate, args) 

    name == 'length' ? 4 : result 
} 

// Test it 
assert "i_do_not_have_4_chars".length() == 4 
+0

왜 이것이 받아 들여지지 않았는지 궁금해 할 수도 있습니다. 답변 : 이것이 대답의 해답이라고 언급 한 후에 제출되었습니다. – IttayD

+0

다른 답변을 수락 할 수 있고 더 나은 것으로 판단되면이 답변을 수락 할 수 있습니다. 녹색 확인 표시를 클릭하여 승인을 취소하십시오. –

관련 문제