方法返回重载意味着编写具有不同返回类型的相同方法。JVM 允许这样做,尽管 Java 不允许。Groovy 可以,但它无法正确解析将调用哪个方法。有一些语言支持这一点,如 C++、Haskell、Perl 和 Ada。
至于你想要什么,是的,只需返回方法应该返回的任何内容并def
作为方法的返回类型。如果您不想要返回类型,则需要anddef
的超类型(编译器可以在使用 时推断出)。List<Foo>
Foo
CompileStatic/TypeChecked
对于调用者,旧的instanceof
(或 switch-case)可以解决问题:
class Foo{}
class Database {
def query(String query) {
if (query.contains(".id")) { // here you will make a call to database
new Foo()
} else {
[]
}
}
}
db = new Database()
assert db.query("from Foo f where f.id = 3") instanceof Foo
assert db.query("from Foo f") instanceof List
更新:
编译器将推断一个常见的超类型作为返回类型。如果它不是具有您尝试使用的方法的东西,您将不得不根据它“分叉”。如果您不喜欢s ,那么有一个扩展可以进行模式匹配:if
import groovy.transform.CompileStatic
@CompileStatic
class Cases {
static main(args) {
def returned = new Cases().query 10
//returned[1] // doesn't work: returned is of the common type
// OBJECT, which has no getAt method
returned.case {
when String then { println it } // will print "a string"
when List then { List l -> println l.head() } // compiles fine, won't be executed
}
}
def query(obj) {
if (obj == 10) {
"a string"
} else {
[1, 2, 3]
}
}
}
这是 Groovy 推理的亮点:
import groovy.transform.CompileStatic
@CompileStatic
class Cases {
static main(args) {
assert new Cases().foo().baz == "w00t"
}
def foo() {
new Foo(baz: "w00t")
}
}
class Foo { String baz }
您编写def foo()
并且它知道该方法将返回一个Foo
对象。美丽的。
如果可能的实现中有一个共同的超类,它将被选中:
import groovy.transform.CompileStatic
@CompileStatic
class Cases {
static main(args) {
def bat = new Cases().animal 1
assert bat.name == "bat"
assert bat.favoriteBloodType == "A+" // Won't compile with error
// "No such property: favoriteBloodType
// for class: Animal"
}
def animal(int animalCode) {
if (animalCode == 1) {
new Bat(name: "bat", favoriteBloodType: "A+")
} else {
new Chicken(name: "chicken", weight: 3.4)
}
}
}
abstract class Animal {
String name
}
class Bat extends Animal {
String favoriteBloodType
}
class Chicken extends Animal {
BigDecimal weight
}
Foo
在您的情况下,编译器将推断两者的共同超类型List
: Object
。