2015-04-17 28 views
1

以下Groovy特性實現了GroovyInterceptable接口,以允許在方法調用之前和之後執行代碼。訪問特性中實現的invokeMethod()內的屬性

trait Bar implements GroovyInterceptable { 
    def bar = "bar" 

    @Override 
    invokeMethod(String name, Object args) { 
     System.out.println(bar) 
     metaClass.getMetaMethod(name, args).invoke(this, args) 
    } 

    def doSomething() { 
    } 
} 

下面的類實現了特徵Bar

class Foo implements Bar { 
} 

看看下面的代碼。

def foo = new Foo() 
foo.doSomething() 

doSomething()呼叫正在invokeMethod()截獲。發生java.lang.StackOverflowError是因爲訪問invokeMethod()內部的屬性bar隱式地調用了bar的獲取者,而該又被invokeMethod()攔截,只是試圖再次訪問bar

如何在不調用該屬性的getter或setter的情況下訪問invokeMethod中的類屬性?

結合性狀使用[email protected]訪問屬性不起作用。

調用截獲的方法的代碼metaClass.getMetaMethod(name, args).invoke(this, args)可能是不正確的,儘管它在類中直接使用特徵邏輯時有效。

編輯的解決方案:

接受的答案貢獻的用戶Opal的作品就像一個腳本環境中的魅力。由於性狀是一個更大的項目的一部分,並在自己的文件中定義的我做了這樣的工作:

package com.example.project 

trait Bar implements GroovyInterceptable { 
    def bar = "bar" 

    @Override 
    invokeMethod(String name, Object args) { 
     System.out.println(this.com_example_project_Bar__bar) 
     metaClass.getMetaMethod(name, args).invoke(this, args) 
    } 

    def doSomething() { 
    } 
} 
+1

試試'這個。@ bar'?隨着2.4.0它正常工作。 – Opal

+0

@Opal感謝您的快速回復。是的,它適用於'this。@ bar'。我想這個例子並不完整,我的問題稍微複雜一點,所以我編輯了示例代碼。 – EightBitBoy

+0

我可以添加它作爲接受的答案嗎? – Opal

回答

1

事實證明,沒有必要使用@直接字段訪問:

trait Bar implements GroovyInterceptable { 
    def bar = "bar" 

    @Override 
    invokeMethod(String name, Object args) { 
     System.out.println(Bar__bar) 
     metaClass.getMetaMethod(name, args).invoke(this, args) 
    } 

    def doSomething() { 
    } 
} 

class Foo implements Bar { 
} 

def foo = new Foo() 
foo.doSomething() 
+0

這看起來正確,我得到這個異常:'MissingPropertyException:沒有這樣的屬性:Bar__bar類:de.appplant.workshop.data.Foo' – EightBitBoy

+0

奇怪。它在我的機器上運行正常。 – Opal

+0

是的,根據[文檔](http://docs.groovy-lang.org/latest/html/documentation/#_public_fields)它的工作原理。我正在使用Android Studio和Groovy 2.4.3。 – EightBitBoy