V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
voidmnwzp
V2EX  ›  Java

为什么泛型接口的实现类在类型擦除后多出了一个保留了原来的参数的方法?

  •  
  •   voidmnwzp ·
    NullpointerW · 2019-12-27 18:28:30 +08:00 · 2825 次点击
    这是一个创建于 1553 天前的主题,其中的信息可能已经有所发展或是发生改变。

    (或者是新增了一个参数和返回都是 object 的方法?

    接口:

     public  interface  itest<T> {
       T test(T s);
    } 
    

    实现类:

    public class test implements itest<String>{
        @Override
        public  String test(String s) {
            return "test";
        }
        public static void main(String[] args) throws NoSuchMethodException {
            Method[] testMethods = test.class.getMethods();
            System.out.println("----------test-----------");
            for (Method testMethod : testMethods) {
                if (testMethod.getName().equals("test")) {
                    System.out.println("returnType : " + testMethod.getParameterTypes()[0]);
                    System.out.println("parameterTypes :" + testMethod.getReturnType());
                }
            }
            System.out.println("----------itest----------");
            Class<?>[] interfaces = test.class.getInterfaces();
            Class<?> itest = interfaces[0];
            Method[] itestMethods = itest.getMethods();
            for (Method itestMethod : itestMethods) {
                if (itestMethod.getName().equals("test")) {
                    System.out.println("returnType : " + itestMethod.getParameterTypes()[0]);
                    System.out.println("parameterTypes :" + itestMethod.getReturnType());
                }
            }
        }
    }
    

    结果:

    ----------test-----------
    returnType : class java.lang.String
    parameterTypes :class java.lang.String
    returnType : class java.lang.Object
    parameterTypes :class java.lang.Object
    ----------itest----------
    returnType : class java.lang.Object
    parameterTypes :class java.lang.Object
    

    求高人解答下 谢谢

    5 条回复    2019-12-28 15:22:03 +08:00
    lazyfighter
        1
    lazyfighter  
       2019-12-27 18:35:15 +08:00
    泛型的本质是强转,只是编译器帮你做了
    voidmnwzp
        2
    voidmnwzp  
    OP
       2019-12-27 18:41:34 +08:00
    是因为类型擦除后 test 类 不存在 和 itest 中的方法签名相同的方法,所以自动加了一个和接口中签名一样的方法?
    optional
        3
    optional  
       2019-12-27 18:47:58 +08:00
    对,java 的泛型就是这么『简陋』。
    guyeu
        4
    guyeu  
       2019-12-28 11:29:07 +08:00
    其实我是想知道反射调那个原始参数的方法为什么会抛异常。。。
    shily
        5
    shily  
       2019-12-28 15:22:03 +08:00
    学习了。

    类型擦除后,itest 就没有类型了,变成了

    public interface itest {
    Object test(Object o);
    }

    为了让 test 实现 itest 接口,编译器帮忙实现了一个接口
    public Object test(Object o) {
    String s = (String) o;
    return test(s);
    }

    这样就多了一个方法。

    如果使用 itest<String> t = new test() 然后调用 String v = t.test("123")
    就会变成 String v = (String) t.test("123") ; // 就是调用 Object test(Object)
    如果使用 test t = new test() 然后调用 String v = t.test("123")
    就会变成 String v = t.test("123") ; // 就是调用 String test(String)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1122 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:50 · PVG 06:50 · LAX 15:50 · JFK 18:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.