微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么Java声称在涉及有界泛型时有2个声明的方法?

具有以下定义:
public interface BaseService<T,ID> {

    T findOne(ID id);

}

public class BaseServiceImpl<T,ID extends Serializable> implements BaseService<T,ID> {

    @Override
    public T findOne(ID id) {
        return null;
    }

}

为什么BaseServiceImpl.class.getDeclaredMethods()返回2个方法

> public java.lang.Object BaseServiceImpl.findOne(java.io.Serializable)
> public java.lang.Object BaseServiceImpl.findOne(java.lang.Object)

有没有办法过滤掉这些?

解决方法

这是类型擦除的结果.在字节代码级别,通用签名只是方法的附加属性,不用于JVM的方法分派.实际的字节代码级别签名是从类型变量绑定的第一种类型派生的,例如对于类型变量T extends Number& Serializable,原始签名替代T将是Number.

为了你的声明,

public interface BaseService<T,ID> {
    T findOne(ID id);
}

T和ID用Object代替;方法的擦除签名是Object findOne(Object).

对于子类型声明

public class BaseServiceImpl<T,ID> {
    @Override
    public T findOne(ID id) {
        return null;
    }
}

删除的ID类型扩展Serializable是Serializable,这使得实现方法具有已擦除的签名对象findOne(Serializable).

为了确保代码使用BaseService接口,调用方法Object findOne(Object),将找到实现方法,编译器生成一个具有签名对象findOne(Object)的bridge method,并包含一个对象findOne(Serializable)的普通委托,必要时执行类型转换.

您可以通过在Method实例上调用isBridge()来识别桥接方法.

您还可以使用类型擦除如何影响结果的知识.通过将声明更改为

public class BaseServiceImpl<T,ID extends Object&Serializable>
      implements BaseService<T,ID> {
    @Override
    public T findOne(ID id) {
        return null;
    }
}

关于泛型类型系统没有语义差异,但ID的扩展扩展了Object& Serializable将是Object,因此,findOne方法的结果擦除将与接口方法的擦除相同,没有桥接方法在这种情况下需要.

原文地址:https://www.jb51.cc/java/128655.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐