2010-08-23 16 views
7

Bir Java sınıfının yöntemini yeniden uygulamak istiyorum. Örneğin, "hi".length() döndürmek için. (Bunu nasıl yapabilirim?Dize # uzunluğunu yeniden tanımlayabilir miyim?

SomeClass.metaClass kullanarak biliyorum Mevcut bir yönteme başvuruda bulunabilir ve yeni (veya geçersiz kılan) yöntemi tanımlayabilirim, ancak mevcut Java yöntemleri için bunu yapamıyorum.

+0

4 dönmek String.length() nasıl İstediğiniz örnek, yani bu. Dizginizi belirli bir maksimum uzunluğa uzatacak bir 'pad()' yöntemini kullanabilirsiniz. O zaman bu dizede uzunluğu arayabilirsin. – Nate

+0

Bununla ne yapmayı seviyorsunuz? Bu şekilde çok fazla kod kırıyorsun. –

+0

Neden? Bunu yaparak kaç kere kırılmaya yatkınsınız? 2 + 2 = 5 yapabilirim, ama gerçekten en iyi çözüm olmayabilir. Belki de bazı özel durumlarda iade edilen değeri ayarlamak istersiniz? – mickeyf

cevap

2

abusing Dize metaClass ile mümkün olabileceği gibi görünüyor. Ama şu ana kadar harika konsolda yaptık girişimi beklenen sonuca yol açmıştır vermedi:

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

println "hi".length() 

Sana Proxy MetaClass veya Delegating metaClass bakmak düşünüyorum üzücü 2

çıkarır.

+0

Sorunun bu sorunla ilgili olduğunu düşünüyorum: http://jira.codehaus.org/browse/GROOVY-3493 –

+1

Öyle görünüyor ki, bu işler: String.metaClass.invokeMethod = {String methodName, args -> println (" merhaba ") } " merhaba ".length() // baskı" merhaba " – IttayD

+0

Bu yanıt, yazarın kendi isteği ile çalışırken aslında neden çalışmadı? –

1

Yeniden tanımladıysanız, yalnızca Groovy kodunda çalışır. Groovy, Java kodunun yürütme şeklini değiştiremez. Groovy ise

, "hi".length() bu Java eşdeğerdir:

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

Groovy aslında aramıyor Çünkü uzunluğu doğrudan metaclass hileler Groovy kod çalışır. Ama Java, MetaClasses'ı bilmiyor, bu yüzden bu işi yapmanın bir yolu yok.

+0

evet, lütfen, sadece nasıl sadece bu nasıl kabul edilemez olduğunu merak olabilir diğerleri için not – IttayD

4

Groovy'yi kullanarak, kendi uygulamanızla herhangi bir yöntemi (son sınıfların bile) değiştirebilirsiniz. Groovy'de yöntem değiştirme, miras değil meta nesne protokolünü kullanır.

Burada hep yanlış bir davranış olur

// 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

bir cevap: Ben bu cevabın bu çözüm cevabın – IttayD

+0

üzerinde olduğunu yorumladıktan sonra gönderilmiştir. Diğer cevabı kabul edemez ve daha iyi olduğunu düşünüyorsanız bunu kabul edebilirsiniz. Unutmak için yeşil onay işaretini tıklamanız yeterlidir. –

İlgili konular