Java泛型 - 寻找一种方法来告诉我泛型类型的超类型

 阳光美女新干线- 发布于 2023-02-13 18:20

的超类型

SomeClass   

Someclass 

而不是

SomeClass  

我正在寻找一个返回泛型类实例的超类型的方法.类似 getGenericSuperclass()的的Class(虽然不能完全像它- getGenericSuperclass()只返回一个类,而通用的可以扩展和由多个在为界:

例如.:

Someclass 

当我getGenericSuperclass()在泛型类的实例上运行时,我得到Object了回报.

在Java中是否有这样的方法,告诉我在其上实例化对象的泛型类型的超类型?

// ===================

编辑:对@jwa的答案的冗长评论如下:

我理解在编译时对泛型进行了类型检查.但是,JVM仍然可以使用类型推断的结果尽可能具体地绑定运行时类型,并至少返回超类型的定义,而不仅仅返回Object作为超类型.此信息在运行时清晰可用.但我收集它不是这样做的.

注意:尚未深入研究类型擦除.

// =================================

EDIT2:

在这个页面中引用术语"有界类型参数" ,我一直在寻找一种方法来返回对象的"绑定类",

这是示例中的可比较

public class Node> {

private T data;
private Node next;

public Node(T data, Node next) {
    this.data = data;
    this.next = next;
}

public T getData() { return data; }
// ...
}

在同一页面上.

在那些页面或其他任何地方都没有它的痕迹 - 我猜Java没有这样做.

1 个回答
  • 你需要看看"类型擦除".实质上,当您的Java代码被编译为字节码时,通用信息将丢失(或"擦除").这就是为什么你找不到任何通过反射类查询泛型类型的方法.

    我在SO上找不到关于类型擦除的好答案,但Wikiepdia似乎有一个合理的描述.

    值得注意的是,选择类​​型擦除是为了在java 1.5和1.4之间提供向后兼容性.其他语言的实现方式不同.例如,.NET完全支持字节代码中的泛型 - 并且允许这些方法作为其反射API的一部分.


    考虑这个类,它使用类型和非类型列表:

    import java.util.List;
    
    public class CastExample <T extends Object> {
        public List<T> typedList;
        public List<?> untypedList;
    
        public T getFirstElement() {
            return typedList.get(0);
        }
    
    
        public T getFromUntypedArray() {
            return (T) untypedList.get(0);
        }
    }
    

    在字节代码中编码这两种方法的方式没有区别.我们可以看到这个javap,特别是javap -c CastExample:

    /var/tmp-> javap -c CastExample
    
    Compiled from "CastExample.java"
    public class CastExample<T> {
      public java.util.List<T> typedList;
    
      public java.util.List<?> untypedList;
    
      public CastExample();
        Code:
           0: aload_0       
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return        
    
      public T getFirstElement();
        Code:
           0: aload_0       
           1: getfield      #2                  // Field typedList:Ljava/util/List;
           4: iconst_0      
           5: invokeinterface #3,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
          10: areturn       
    
      public T getFromUntypedArray();
        Code:
           0: aload_0       
           1: getfield      #4                  // Field untypedList:Ljava/util/List;
           4: iconst_0      
           5: invokeinterface #3,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
          10: areturn       
    }
    

    每个操作的确切含义并不过分重要.重要的是它调用完全相同的操作,两者之间没有区别.

    2023-02-13 18:22 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有