Groovy 重载方法的意外行为

Groovy 重载方法的意外行为,groovy,Groovy,我对groovys方法重载行为有点困惑:给定类 在下面的测试中,我对teststringnull和testBStringNull 抛出不明确的方法调用异常,但为什么对 testANull和testBNull然后呢 更重要的是:testBNull(null) 调用字符串foo(一个参数)?我猜对象不知道它绑定到的变量的类型,但是为什么这个调用对groovy来说并不含糊,而其他调用却含糊不清呢 (我希望我解释得足够好,我的头因产生这种轻微的疼痛而疼痛 例如。) 测试: import org.juni

我对groovys方法重载行为有点困惑:给定类 在下面的测试中,我对
teststringnull
testBStringNull
抛出不明确的方法调用异常,但为什么对
testANull
testBNull
然后呢

更重要的是:
testBNull(null)
调用
字符串foo(一个参数)
?我猜对象不知道它绑定到的变量的类型,但是为什么这个调用对groovy来说并不含糊,而其他调用却含糊不清呢

(我希望我解释得足够好,我的头因产生这种轻微的疼痛而疼痛 例如。)

测试:

import org.junit.Test
import Foo.A
import Foo.B

class FooTest {
    Foo foo = new Foo()

    @Test
    void testA() {
        A a = new A()
        assert foo.foo(a) == 'a'
    }

    @Test
    void testAString() {
        A a = new A()
        assert foo.foo('foo', a) == 'a'
    }

    @Test()
    void testANull() {
        A a = null
        assert foo.foo(a) == 'a'
    }

    @Test
    void testAStringNull() {
        A a = null
        assert foo.foo('foo', a) == 'a'
    }

    @Test
    void testB() {
        B b = new B()
        assert foo.foo(b) == 'b'
    }

    @Test
    void testBString() {
        B b = new B()
        assert foo.foo('foo', b) == 'b'
    }

    @Test
    void testBNull() {
        B b = null
        assert foo.foo(b) == 'b'
    }

    @Test
    void testBStringNull() {
        B b = null
        assert foo.foo('foo', b) == 'b'
    }

}
这是Groovy的多重分派机制的一个(鲜为人知的)奇怪之处,它试图调用“最合适的”方法,同时提供的静态类型(在您的例子中是a或B)没有用作分派机制的一部分。当您声明A=null时,您得到的不是类型为A的null引用,而是对null对象的引用

最终,为了安全地处理重载方法的可能为空的参数,调用方必须强制转换参数,如中所示

A a = null
assert foo.foo('foo', a as A) == 'a'

这次讨论可能会对这个问题有所帮助。

回答得好。嘿,难道没有关于“来自最近类的路径”的东西与此相关吗?如何编写一个不使用“a作为a”而不使用null的方法?我不想得到不明确方法的例外。
A a = null
assert foo.foo('foo', a as A) == 'a'