Groovy не предлагает неявного принуждения, но динамические возможности языка позволяют переопределить methodMissing()
для класса вызываемого (в зависимости от того, является ли метод вызываемого объекта статическим, methodMissing()
или $static_methodMissing()
должны быть переопределены, см. документы ):
class ShrewdCalculator {
static void accept(Currency o) {
println o
}
static def $static_methodMissing(String name, def args) {
if (name == "accept" && args.size() == 1 && args[0].class == String) {
return accept(Currency.valueOf(args[0]))
}
throw new MissingMethodException(name, this.class, args)
}
}
, где Currency
например,
enum Currency {
US_DOLLAR, EURO
static valueOf(String s) {
if (s == "USD") return US_DOLLAR
if (s == "EUR") return EURO
throw new RuntimeException("No currency defined for input $s")
}
}
Тогда вызов метода даст следующие результаты:
ShrewdCalculator.accept(Currency.US_DOLLAR) // --> US_DOLLAR
ShrewdCalculator.accept("USD") // --> US_DOLLAR thanks to fallback on methodMissing()
ДругойМожно добавить метод принуждения к ExpandoMetaClass
класса String
и просто использовать Object
в сигнатуре метода только для принудительного его принудительного применения:
class ShrewdCalculator {
static {
String.metaClass.asType(Currency) {
return Currency.valueOf(this)
}
}
static void accept(Object o) {
println o as Currency
}
}
В этом случаеметод будет работать так:
ShrewdCalculator.accept(Currency.US_DOLLAR) // --> US_DOLLAR because Currency as Currency is no-op
ShrewdCalculator.accept("USD") // --> US_DOLLAR thanks to coercion defined in String's metaclass
Ни один из этих методов не похож на последствия Scala.