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

2019-12-27 18:28:30 +08:00
 voidmnwzp

(或者是新增了一个参数和返回都是 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

求高人解答下 谢谢

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/632971

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX