加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

groovy – 重载方法的意外行为

发布时间:2020-12-14 16:31:21 所属栏目:大数据 来源:网络整理
导读:对于groovys方法重载行为我有点困惑:给定类 和下面的测试,我很可能与testAStringNull和testBStringNull 抛出暧昧的方法调用异常,但为什么不是这样的 那么testANull和testBNull? 而且更重要的是:为什么testbean(null) 调用String foo(A arg)?我猜对象不知
对于groovys方法重载行为我有点困惑:给定类
和下面的测试,我很可能与testAStringNull和testBStringNull
抛出暧昧的方法调用异常,但为什么不是这样的
那么testANull和testBNull?

而且更重要的是:为什么testbean(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'
    }

}

解决方法

Groovy的多调度机制(一些鲜为人知的)奇怪,它试图引用“最合适”的方法,结合提供的静态类型(在你的情况下是A或B)不被用作调度机制的一部分.当您声明A a = null时,您获得的不是A类的空引用,而是对NullObject的引用.

最终,为了安全地处理可能的null参数以重载方法,调用者必须转换参数,如in

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

这个关于“Groovy Isn’t A Superset of Java”的讨论可能会对这个问题有所了解.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读