2016-12-19 172 views
3

我不確定是否可以將kotlin擴展設置爲java對象。設置kotlin擴展

在我的程序中,我有一個叫做Submission的java類,我想創建一個名爲categories的kotlin擴展 - 一個ArrayList - 所以我這樣做了。

var Submission.categories: ArrayList<String> 
    get() { 
     return this.categories 
    } 
    set(categories){ 
     this.categories = categories 
    } 

但是每當我試圖設置一個類別的程序只是一個的StackOverflowError這樣的崩潰:

ERR: stack=java.lang.StackOverflowError: stack size 8MB 
      at com.....setCategories(Extensions.kt:0) 
      at com.....setCategories(Extensions.kt:19) 
      at com.....setCategories(Extensions.kt:19) 
      at com.....setCategories(Extensions.kt:19) 
      at com.....setCategories(Extensions.kt:19) 
      at com.....setCategories(Extensions.kt:19) 

這似乎是宣告科特林擴展正確的語法。所以我真的不確定我應該怎樣去解決這個問題。也許我應該只是使用普通的舊繼承?

謝謝。

+0

你沒有在setters中的getter中定義任何自定義邏輯,那麼爲什麼你需要它們?這個問題是由不正確的setter聲明造成的,'this.categories = categories'將調用'set()'方法,這將導致無限循環。 – Egor

+0

@Egor啊,這很有道理。我定義get和set方法的原因是因爲它拒絕在沒有get方法和return語句的情況下進行編譯。我認爲它也是一樣的,也是這樣做的。我將嘗試刪除設置的邏輯,看看會發生什麼。 – nmu

回答

4

您的代碼會拋出StackOverflowError,因爲它會遞歸調用它自己。 this.categories只是調用它已經在的吸氣劑和this.categories = categories調用它已經在其中的設置器。

擴展屬性只是一對(擴展)getter和setters的語法糖。在屬性訪問器(即getter和setter)中,您只能訪問已從接收器類訪問的內容。如果它具有公共字段,則可以訪問它們,但是不能定義新字段。如果你想保存更多的狀態,但是這個類沒有API,那麼你運氣不好。

什麼是可變擴展屬性通常會做的是重定向到現有的變異函數。這是一個例子。

//java 
class Foo { 
    private List<String> items; 

    public String myItems() { 
     return items; 
    } 
} 


//kotlin 
var Foo.firstItem: String 
    get() = myItems()[0] 
    set(value) { 
     myItems()[0] = value 
    } 
+0

即使在修改我的getter和setter以避免遞歸調用之後(如您所指出的那樣)。 stackOverflowError只是移動到get()。但是,如果我正確理解您的帖子,這不應該工作,因爲'類別'不是這個程序中的公共字段,我試圖定義一個新字段。所以我想這是根本問題。 – nmu

+4

我完全同意這個答案,但可能值得一提的是,雖然擴展不能修改類來添加支持字段,但額外的狀態仍然可以存儲在類之外的某個地方,代表可以在這裏幫助。有關此解決方法的更多詳細信息,請參閱:http://stackoverflow.com/a/36511438/2196460 – hotkey

+0

@hotkey感謝您的鏈接。可以肯定的是,這是否可以與java類一起工作 – nmu