voidmnwzp
V2EX  ›  Java

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

  •  
  •   voidmnwzp ·
    NullpointerW · Dec 27, 2019 · 3389 views
    This topic created in 2349 days ago, the information mentioned may be changed or developed.

    (或者是新增了一个参数和返回都是 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 replies    2019-12-28 15:22:03 +08:00
    lazyfighter
        1
    lazyfighter  
       Dec 27, 2019
    泛型的本质是强转,只是编译器帮你做了
    voidmnwzp
        2
    voidmnwzp  
    OP
       Dec 27, 2019
    是因为类型擦除后 test 类 不存在 和 itest 中的方法签名相同的方法,所以自动加了一个和接口中签名一样的方法?
    optional
        3
    optional  
       Dec 27, 2019
    对,java 的泛型就是这么『简陋』。
    guyeu
        4
    guyeu  
       Dec 28, 2019
    其实我是想知道反射调那个原始参数的方法为什么会抛异常。。。
    shily
        5
    shily  
       Dec 28, 2019
    学习了。

    类型擦除后,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)
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5998 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 70ms · UTC 02:57 · PVG 10:57 · LAX 19:57 · JFK 22:57
    ♥ Do have faith in what you're doing.