使用两个不同的setter在Groovy中设置属性值
我希望允许用户使用使用两个不同的setter在Groovy中设置属性值,groovy,Groovy,我希望允许用户使用BigDecimal和String在我的类中设置BigDecimal属性(出于向后兼容的原因) 它尝试使用两个具有不同参数类型的setter: class PitestPluginExtension { BigDecimal timeoutFactor void setTimeoutFactor(BigDecimal timeoutFactor) { this.timeoutFactor = timeoutFactor } @
BigDecimal
和String
在我的类中设置BigDecimal
属性(出于向后兼容的原因)
它尝试使用两个具有不同参数类型的setter:
class PitestPluginExtension {
BigDecimal timeoutFactor
void setTimeoutFactor(BigDecimal timeoutFactor) {
this.timeoutFactor = timeoutFactor
}
@Deprecated
void setTimeoutFactor(String timeoutFactor) {
//display deprecation warning
this.timeoutFactor = timeoutFactor.toBigDecimal()
}
}
但是Groovy在以下方面失败了:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object
'2.12' with class 'java.lang.String' to class 'java.math.BigDecimal'
如果直接调用setter,那么一切都可以正常工作,但这是一个非常复杂的问题,人们习惯于使用属性赋值
是否可以告诉Groovy(1.8.6)在属性赋值上使用不同的输入类型(最好不使用Groovy元编程)?以下解决方案(由@Don的答案暗示!)似乎有效,因为1.21
asbigdecimic
被无损地转换为String
,并在setter中使用。稍后,它可以作为BigDecimal
获得
class PitestPluginExtension {
BigDecimal timeoutFactor
void setTimeoutFactor(String timeoutFactor) {
this.timeoutFactor = new BigDecimal(timeoutFactor)
}
}
def extension = new PitestPluginExtension()
extension.timeoutFactor = "1.81"
assert extension.timeoutFactor == 1.81
extension.timeoutFactor = 1.21
assert extension.timeoutFactor == 1.21
为什么没有元编程?@WillP,扩展类是由Gradle管理的(请参阅配置),在这个类上执行的内部Gradle魔术可能(可能)存在一些问题。因此,我更喜欢使用“标准”方法的清晰解决方案(比如具有不同参数类型的setter——不幸的是,这不起作用)。然而,如果它在Groovy中不“可能”,那么使用元编程的(工作)解决方案也可以。很好的技巧,谢谢你的回答。我不喜欢的是,
newbigdecimal(1.11)
执行BigDecimal(double val)
,而通常1.11.class==java.math.BigDecimal
。这迫使我在传递值之前对其进行四舍五入。然而,你的想法给了我另一个暗示。
import java.math.*
class PitestPluginExtension {
private BigDecimal timeoutFactor
void setTimeoutFactor(timeoutFactor) {
this.timeoutFactor = new BigDecimal(timeoutFactor)
}
def getTimeoutFactor() {
this.timeoutFactor
}
}
// ignore differences due to precision errors
void compareImprecisely(BigDecimal expected, BigDecimal actual) {
BigDecimal roundedExpected = Math.round(expected * 100) / 100
BigDecimal roundedActual = Math.round(actual * 100) / 100
assert roundedExpected == roundedActual
}
def ppe = new PitestPluginExtension()
def expected = new BigDecimal('1.11')
// test assigning a string
ppe.timeoutFactor = '1.11'
compareImprecisely expected, ppe.timeoutFactor
// test assigning a BigDecimal
ppe.timeoutFactor = 1.11
compareImprecisely expected, ppe.timeoutFactor
class PitestPluginExtension {
BigDecimal timeoutFactor
void setTimeoutFactor(String timeoutFactor) {
this.timeoutFactor = new BigDecimal(timeoutFactor)
}
}
def extension = new PitestPluginExtension()
extension.timeoutFactor = "1.81"
assert extension.timeoutFactor == 1.81
extension.timeoutFactor = 1.21
assert extension.timeoutFactor == 1.21