2016-12-19 126 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