Неожиданное поведение с перегруженными методами

Я немного озадачен поведением перегрузки метода groovys: учитывая класс и тесты, приведенные ниже, я довольно хорошоtestAStringNull а такжеtestBStringNull бросая неоднозначные исключения вызова метода, но почему это не так дляtestANull а такжеtestBNull затем?

И, что гораздо важнее: почемуtestBNull(null) вызовString foo(A arg)? Я думаю, что объект нене знаю о типе переменной этоОбязательно, но почему этот призыв не является двусмысленным, в то время как другие?

(Надеюсь, я объяснил достаточно хорошо, у меня болит голова от генерации этого минимального примера.)

class Foo {
    static class A {}
    static class B {}

    String foo(A arg) { return 'a' }

    String foo(String s, A a) { return 'a' }

    String foo(B arg) { return 'b' }

    String foo(String s, B b) { return 'b' }
}

тесты:

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'
    }

}

Ответы на вопрос(1)

Ваш ответ на вопрос