public class A {
    void meth1()
    {

    }
}
public class B extends A{
    void meth2()
    {

    }
}

public class generic_class<T extends A> {
    T var1;

    public void meth4(generic_class<? extends B> gc)
    {
        gc.var1.meth2();
    }
}

在这里,我已经宣布了generic_class's meth4个通配符<? extends B>.据我所知,在运行时不存在泛型,所有的‘T’都会被‘A’的上限所取代.所以var1是‘A’类型的,那么它怎么能够访问在B中声明的方法2()呢?作为一个超类,它不应该知道它的派生类的属性和方法.

推荐答案

查看字节码可以了解发生了什么(我将类A重命名为Base,B重命名为Sub,generic_class重命名为Test).这是我在字节码中看到的(使用javap -c Test):

Compiled from "Test.java"
public class Test<T extends Base> {
  T var1;

  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public void meth4(Test<? extends Sub>);
    Code:
       0: aload_1
       1: getfield      #2                  // Field var1:LBase;
       4: checkcast     #3                  // class Sub
       7: invokevirtual #4                  // Method Sub.meth2:()V
      10: return
}

T的出现被视为基数.然后将其转换为Sub,因为这是方法param的泛型约束,然后调用所需的方法,从而实现所需的功能,尽管存在类型擦除.

Java相关问答推荐

Java .类参数不通过构造函数传递

确定Java中Math.Ranb()输出的上限

Spring Boot@Cachebale批注未按预期工作

GetChildren().emoveAll()不会删除 node

使SLF4J在Android中登录到Logcat,在测试中登录到控制台(Gradle依赖问题)

如何在antlr4中跳过所有反斜杠-换行符而保留换行符?

Java SSLKeyManager出厂密码

有没有可能在时间范围内得到多种解决方案?

二进制数据的未知编码/序列化

Cordova Android Gradle内部版本组件不兼容

如何使这两种方法合二为一?

如何生成指定范围内的11位序列号?

找出承载Cargo 的最小成本

具有最大共同前景像素的图像平移优化算法

为什么项目名称出现在我的GET请求中?

如何将RESTAssured';S的Http标题转换为<;字符串、字符串和>的映射?

控制器建议异常处理

PhantomReference无法访问时会发生什么?

OpenJDK20:JEP434:Foreign Function&;内存API(第二次预览)

语句打印在错误的行(Java Token 问题)