2017-07-14 111 views
2

我想用一个科特林数据类作为一个例外,它似乎很动听:科特林构造属性和调用不同的超构造

data class MyException(val extraData: Any) : RuntimeException() 

我还希望能够在cause传递到在那些存在的情况下超级班。不幸的是,数据类只能在它们的主构造函数中有val/var,并且由于默认的构造函数调用无参数构造函数,所以似乎我根本无法做到这一点,因为没有总是要求cause被传递,存储为在我的班级,我不想要的领域。

我想是这样的:

data class MyException(val extraData: Any) : RuntimeException() { 
    constructor(extraData: Any, cause: Throwable) : this(extraData) super(cause) {} 
} 

看来,即使我不使用数据类,我现在还不能使用便捷的var/val构造辅助函数,因为它们可以只能在必须选择使用哪个超级构造函数的主构造函数上。我能想出最好的是这个,这是相当详细的:

class MyException : RuntimeException { 
    val extraData: Any 

    constructor(extraData: Any) { 
     this.extraData = extraData 
    } 

    constructor(extraData: Any, cause: Throwable) : super(cause) { 
     this.extraData = extraData 
    } 
} 

我错过了什么吗?是否真的没有办法根据重载的构造函数有条件地调用不同的超类构造函数,并且仍然能够使用参数语法var/val?如果是这样,为什么?有没有更好的方法做这种事情?

回答

1

你想要的是有这样一个普通班完全是可行的:

class MyException(val extraData: Any, cause: Throwable? = null) : RuntimeException(cause) 

在这里你有一个主构造函数,它总是发生在extraData,使物业出来。它也接受异常原因,但它只将它传递给超类构造函数(注意在第二个参数之前不存在val)。它还利用Kotlin中的默认参数,它允许您不指定原因。

不幸的是,你不能在你的情况下专门使用数据类,因为他们的主要构造函数不允许有常规参数。您也必须将原因声明为属性。数据类应该用于最简单的情况,而且你有更复杂的情况。

如果超类需要使用两个不同的构造函数进行有条件的初始化,那么您将不得不在类中使用两个不同的构造函数。任何构造函数都必须将超类初始化委托给另一个构造函数,或者自行完成。它不能这样做,因为这意味着超类会被初始化两次,这是没有意义的。在构造函数本身执行之前,超类的初始化和委托都会发生,所以你不能有任何关于哪一个要做的逻辑。

您不能拥有主构造函数,因为它总是需要在存在时进行委托。这意味着属性也必须显式声明,因为属性声明和初始化语法仅适用于主构造函数。

+0

谢谢。这个和@ holi-java的答案对于'Exception'情况来说都很好,因为Exception允许一个空的原因并正确处理它。无法调用不同的超级构造函数并使用'var' /'val'参数的更普遍的问题仍然没有答案。 –

+0

@YonaAppletree简而言之,这是不可能的。但是如果你正在寻找解释,我已经将它添加到答案中。 – Malcolm

2

既然this(...) & super(...)是构造函数中的第一条语句,所以不能同时调用它。否则,您将获得编译时错误。

IF任何类包含一个primary constructor,他们secondary constructors必须显式调用它的主构造,所以你不能在二级构造函数中调用额外super(...)可言。

如果类具有主构造函数,则每个次构造函数需要通过另一个次构造函数直接或间接地委托给主构造函数。代表团同一个类的另一个构造函数使用this关键字

完成,但还有另一种方式通过Throwable#initCause设置的原因,例如:

data class MyException(val extraData: Any) : RuntimeException() { 
    constructor(extraData: Any, cause: Throwable) : this(extraData) { 
     initCause(cause) 
    } 
} 

data class是专为POJO而不是Exception s。