首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么这个泛型不能识别它的超类边界(Java)?

在Java中,泛型是一种参数化类型的机制,它可以在编译时提供类型安全性,并允许在编译时检查和强制类型约束。泛型类或方法可以定义一个或多个类型参数,这些类型参数可以用于指定方法参数、返回类型或类的成员变量的类型。

当我们定义一个泛型类或方法时,可以使用extends关键字来指定泛型的上界,即限制泛型参数必须是某个类的子类或实现了某个接口。例如,我们可以定义一个泛型类Box,其中的类型参数T必须是Number类或其子类:

代码语言:java
复制
class Box<T extends Number> {
    private T value;
    
    public void setValue(T value) {
        this.value = value;
    }
    
    public T getValue() {
        return value;
    }
}

在上述代码中,T extends Number表示T必须是Number类或其子类。这样,我们就可以在Box类中使用Number类的方法,而不需要进行类型转换。

然而,泛型在运行时会被擦除,即泛型类型信息在运行时是不可用的。这就导致了一个问题:无法在运行时识别泛型参数的超类边界。

例如,我们定义了一个泛型方法printValue,该方法接受一个泛型参数,并尝试调用其超类的方法:

代码语言:java
复制
class Utils {
    public static <T extends Number> void printValue(T value) {
        System.out.println(value.intValue());
    }
}

在上述代码中,我们尝试调用Number类的intValue()方法。然而,由于泛型在运行时被擦除,编译器无法确定T的具体类型,因此无法调用intValue()方法。

这是因为Java的泛型是通过类型擦除来实现的,编译器在编译时会将泛型类型擦除为其上界类型或Object类型。因此,在运行时无法获取泛型参数的具体类型信息。

虽然无法在运行时识别泛型参数的超类边界,但我们仍然可以在编译时进行类型检查,以确保泛型参数满足超类边界的要求。这可以提供编译时的类型安全性。

总结起来,泛型不能识别其超类边界是因为泛型在运行时被擦除,导致无法获取泛型参数的具体类型信息。然而,我们仍然可以在编译时进行类型检查以确保类型安全性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

更深入地理解Java

3.1.边界 如前所述,类型参数可以是有界。有界意味着“限制”,我们可以限制方法可以接受类型。 例如,可以指定一个方法接受一个类型及其所有子类(上限)或一个类型所有(下限)。...众所周知,Object是所有Java类型,但是,Object集合不是任何集合类型。...和原始数据类型 Java一个限制是类型参数不能是基本类型 例如,以下内容无法编译: List list = new ArrayList(); list.add(17); 复制代码...为了理解原始数据类型为什么不起作用,只需记住 是编译时特性,这意味着类型将会被擦除,所有类型都实现为 Object 。...Valhalla 工程旨在改进处理方式。其思想是实现JEP 218中描述专门化. 7. 总结 Java是对Java语言一个强大补充,因为使程序员工作更容易,也更不容易出错。

1K30
  • Java细节

    如果没有 学习Java,必不可少一个过程就是需要掌握起源于JDK1.5,为什么我们要使用呢?...使用 JDK1.5给我们带来了,当我们使用容器时候,自然更加推荐使用带有容器,那么为什么那些不具备容器还存在呢?...x.print(); // 输出“hello” } 定义有边界 有的时候,即使是我们想要定义一个,但并不意味着我们就想要任何一个类型都可以作为我们想要定义参数,这个时候怎么办...>无界通配符是不能用做声明或者是方法;而可以,不再赘述。在理解时候,请暂时不要和联系起来,这二者使用没有必然联系!...,而这个“?”到底是什么我不知道,只知道是T,T当然能够上转型到T某个)。这里List就是一个消费者,消费(add)T类型,凭什么能够add,因为ls本身类型是T

    25220

    Java详解,史上最全图文详解「建议收藏」

    大家好,又见面了,我是你们朋友全栈君。 java中有很重要地位,无论是开源框架还是JDK源码都能看到。...本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体值,那样这个类型就可以在使用时决定了。这种参数类型可以用在、接口和方法中,分别被称为接口、方法。...二:为什么使用 好处是在编译时候检查类型安全,并且所有的强制转换都是自动和隐式,提高代码重用率。 (1)保证了类型安全性。...super E>形式, 这里E就是该边界.。 注意: 你可以为一个指定上边界或下边界, 但是不能同时指定上下边界。...: 表示不确定java类型 六:实现原理 本质是将数据类型参数化,通过擦除方式来实现,即编译器会在编译期间「擦除」语法并相应做出一些类型转换动作。

    83330

    java详解

    >):无边界通配符主要作用就是让能够接受未知类型数据 - 固定上边界通配符():使用固定上边界通配符, 就能够接受指定及其子类类型数据。...super E>):使用固定下边界通配符, 就能够接受指定及其父类型数据。要声明使用该类通配符, 采用<?...,Apple和Fruit之间肯定是存在联系,然而编译器却无法识别,那怎么在代码中解决这个问题呢?...这样做目的是因为Java是1.5之后才被引入,为了保持向下兼容性,所以只能做类型擦除来兼容以前代码。对于这一点,如果阅读Java集合框架源码,可以发现有些其实并不支持。...instanceof关键字 我们无法对代码直接使用instanceof关键字,因为Java编译器在生成代码时候会擦除所有相关类型信息,正如我们上面验证过JVM在运行时期无法识别出ArrayList

    33410

    Java 详解

    引言 Java中一个非常重要知识点,在Java集合框架中被广泛应用。本文我们将从零开始来看一下Java设计,将会涉及到通配符处理,以及让人苦恼类型擦除。...边界符 现在我们要实现这样一个功能,查找一个数组中大于某个特定元素个数,我们可以这样实现: ?...但是按照我们通常思维习惯,Apple和Fruit之间肯定是存在联系,然而编译器却无法识别,那怎么在代码中解决这个问题呢?我们可以通过使用通配符来解决这个问题: ?...问题一 在Java中不允许创建数组,类似下面这样做法编译器会报错: ? 为什么编译器不支持上面这样做法呢?继续使用逆向思维,我们站在编译器角度来考虑这个问题。...我们先来看一下下面这个例子: ? 对于上面这段代码还是很好理解,字符串数组不能存放整型元素,而且这样错误往往要等到代码运行时候才能发现,编译器是无法识别的。

    68550

    Java - 细节篇

    ,但实际上跟多态还是有区别的 从本质上来讲,多态是Java一个特性,一个概念,是真实存在一种类型; 目录 下面我们详细说下Java相关知识点,目录如下: 什么是类型参数 为啥要有...演变史 类型擦除 应用场景 通配符限定 动态类型安全 等等 正文中大部分示例都是以集合中为例来做介绍,因为用比较多,大家都熟悉 正文 什么是类型参数 类型参数就是参数类型,接受作为实际值...限定符就是用来限定边界,如果有设置边界,比如,那么擦除时,会擦除到第一个边界Animal,而不是Object 下面还是以上面的代码为例,展示下擦除前后对比...下面开始正经点解释吧 因为这个通配符限定不允许插入任何数据,所以当你指向子类型时,这个list就只能存放指向那个集合里数据了,而不能再往里添加; 自然也就类型安全了,只能访问,不能添加 为什么<?...这个可能是因为编译器也不确定你要返回T是什么类型,所以干脆留给你自己来处理了 但是如果你把这个listDog指向一个父对象,然后又在父对象中,插入其他类型,那可就乱了(又回到<

    79531

    Java漫谈-数组

    Javalength和length() 问:为什么数组有length属性,而字符串没有?或者,为什么字符串有length()方法,而数组没有? 答: 一旦数组被创建,他长度就是固定了。...数组之所以优于之前同期,就是因为可以创建一个数组去持有某种具体类型。 在之前,其他容器在处理对象时,都将他们视为没有任何具体类型,即将这些对象当做Javav中根Object处理。...多维数组中构成矩阵每个向量都可以具有任意长度(这被称为粗糙数组)。 数组与 通常,数组与不能很好结合。不能实例化具有参数化类型数组。...当然,不能总是选择使用参数化方法而不是参数化,但应该成为首选。 容器总是比数据更好选择。...一般而言,会发现或方法边界处很有效,而在或方法内部,擦除通常会使变得不适用。如,不能创建数组。

    1.2K10

    彻底搞懂

    前言 Java高级概念,也是构建框架必备技能,比如各种集合都是实现,今天详细聊聊Java概念,希望有所收获。记得点赞,关注,分享哦。...使用地方是 方法使用地方 Java Java方法 Java接口 /** * @author 香菜 */ public class Player {// private...参数将会被擦除到第一个边界边界可以有多个,重用 extends 关键字,通过它能给与参数类型添加一个边界)。编译器事实上会把类型参数替换为第一个边界类型。...4、创建类型实例 问题:代码中不能new T()原因有两个,一是因为擦除,不能确定类型;而是无法确定T是否包含无参构造函数。...7、总结 相当于创建了一组,方法,虚拟机中没有类型对象概念,在眼里所有对象都是普通对象 ?

    83220

    深入理解 Java

    本文已归档到:「javacore」 本文中示例代码已归档到:「javacore」 1. 为什么需要 JDK5 引入了机制。 为什么需要呢?...由尖括号()分隔类型参数部分跟在名后面。指定类型参数(也称为类型变量)T1,T2,...和 Tn。 一般将名称为原型,而将 指定参数称为类型参数。...方法语法包括一个类型参数列表,在尖括号内,出现在方法返回类型之前。对于静态方法,类型参数部分必须出现在方法返回类型之前。...做了以下工作: 把所有类型参数替换为 Object,如果指定类型边界,则使用类型边界来替换。因此,生成字节码仅包含普通,接口和方法。 擦除出现类型声明,即去掉 内容。...下界通配符 下界通配符将未知类型限制为该类型特定类型或类型。 注意:上界通配符和下界通配符不能同时使用。 语法形式为:<?

    41420

    大师小玩具——精解

    super T> getSuperclass() 返回这个(由于java是单继承,每个子类最多只有一个父)如果T不是一个或T是Object(Object已经是根了,没有),则返回...Java之于C++是青出于蓝,思想也是源于C++,但是在java里落地生根,机制发生了变化,最大变化就是Java编译器需要预先指定边界,以便告知编译器只能接受这个边界类型,超越这个边界类型在该中不予支持...而如果定义了边界,擦除机制会将参数类型擦除到这个边界,就好像在声明中用Sort替换了T一样。 问题:为什么不直接用代替啊?...边界就是发生动作地方。 4. 擦除补偿 前面强调过,不能显式地引用运行时类型操作之中,换句话来讲,就是运行时,一定被具体类型替代。任何试图运行操作举动都将被编译器视为违法。...使用注意事项 1. 任何基本类型都不能作为类型参数。 不能创建类似ArrayList东西。 2. 一个不能实现同一个接口两种变体。

    1.5K50

    Java基础】JavaCore核心-技术

    名 对象名 = new 名(); 注意 创建使用没有指定类型,则默认是object类型 类型从逻辑上看是多个类型,实际都是相同类型 Java 可以创建对应对象和数组引用...,但不能直接创建对象和数组 Java 有类型擦除,任何类型在擦除之后就变成了 Object 类型 因此创建对象就相当于创建了一个 Object 类型对象 所以直接创建对象和数组也行为被编译器禁止...super E>形式 使用固定下边界通配符, 只能够接受指定及其父类型数据。 采用形式, 这里E就是该边界....可以为一个指定上边界或下边界, 但是不能同时指定上下边界 (2)通配符案例实战 //使用通配符,复用性更强 public static void print(NumberCollection...在 Java 中是不能直接创建对象和数组 主要原因是 Java 有类型擦除,任何类型在擦除之后就变成了 Object 类型或者对应上限类型 那定义中如果需要用到数组,如何解决这个问题

    36600

    一文带你玩转“

    extendsE>; extends关键字表示这个参数必须是 E 或者 E 子类。 3、下边界通配符,如 <?...不能够直接实例化类型变量,如:new T(...),newT[...] 或 T.class。 七: 常见面试题 (一) Java是什么 ?   ...答: 是JDK1.5新特性,只是一个语法糖,用于解决、接口、方法、属性对象类型不确定问题。 (二)使用好处是什么?   ...extends E> 表示: 参数必须是E类型或者E子类【这个只能用于方法参数,或者变量中修饰,不能修饰接口或】 下边界通配符 表示: 参数必须是E或者E,直至Object类型【这个只能用于方法参数,或者变量中修饰,不能修饰接口或】 非限定通配符: 使用一个单独T(或者A-Z任意字母)表示,表示没有任何限制

    64420

    Java

    super T> 表示类型下界(Java Core中叫类型限定),表示参数化类型是此类型类型(父类型),直至Object; 上界<?...list中为什么不能加入Father和Father子类呢,我们来分析下。 List表示上限是Father,下面这样赋值都是合法 List<?...比如下面这个方法里,三个T都指代同一个类型,要么都是String,要么都是Integer。 public List fill(T... t); 但通配符<?...extends xxx 只能用于方法返回类型限定,jdk能够确定此类最小继承边界为xxx,只要是这个都能接收,但是传入参数无法确定具体类型,只能接受null传入)。...既不能用于方法参数传入,也不能用于方法返回。 带有super类型限定通配符可以向对象中写入,带有extends子类型限定通配符可以向对象读取。

    1K30

    Java中<? extends T>和<? super T>理解

    super T> 表示类型下界(Java Core中叫类型限定),表示参数化类型是此类型类型(父类型),直至Object; 上界<?...list中为什么不能加入Father和Father子类呢,我们来分析下。 List表示上限是Father,下面这样赋值都是合法 List<?...比如下面这个方法里,三个T都指代同一个类型,要么都是String,要么都是Integer。 public List fill(T... t); 但通配符<?...extends xxx 只能用于方法返回类型限定,jdk能够确定此类最小继承边界为xxx,只要是这个都能接收,但是传入参数无法确定具体类型,只能接受null传入)。...既不能用于方法参数传入,也不能用于方法返回。 带有super类型限定通配符可以向对象中写入,带有extends子类型限定通配符可以向对象读取。

    1.1K10

    看了这篇,下次设计链表别傻傻用int 表示node节点值了

    ——百度百科 没有时候 ,从字面的意思来看,广泛意思,能够广泛代表或者处理某一事务类型(java集合)。在没有时候,你会如何去处理?比如你写链表时候。...使用Object表示 发现在设计上存在这个大问题之后,大大纷纷考虑到这种问题严重和复杂性,随着面向对象发展流行我们知道在java中有向上转型和向下转型....中Object为所有()。...Java 在Object显示转换存在不安全行为情况下,Java在jdk1.5以后提出了机制,通过就能有效避免转型时候出现问题,简单理解就是在、接口、方法中定义未知类型变量,只有初始化时候才知道真正类型...那么在java中有上边界限定和下边界限定用来限制可用类型。 限定通配符包括两种: 类型上界,格式为:,即类型必须为T类型或者T子类 ? 类型下界,格式为:<?

    49820

    JAVA回忆录之

    class文件中我们可以看出来,其实在编译后都进行了擦除,类型T都转化为了Number,然后在需要使用时候进行checkcast。...同样,我们不知道究竟是什么,但我们知道Apple和任何Apple子类都跟类型兼容。...层次问题 可以是层次一部分,就像非那样,因此,可以作为或子类。...桥接方法 子类中重写方法类型擦除不能产生于中方法相同擦除。对于这种情况,会生成使用类型擦除方法,并且这个方法调用具有由子类指定类型擦除方法。当然桥接方法只会在字节码级别发生。...不能抛出也不能捕获实例 扩展Throwable即为不合法,因此无法抛出或捕获实例。

    52030

    Java 中 “T,E,K,V,?” 如何区分?

    Java 中 “T,E,K,V,?” 如何区分?...Java (generics)是 JDK 5 中引入一个新特性, 提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法类型。...中通配符 我们在定义方法,接口时候经常会碰见很多不同通配符,比如 T,E,K,V 等等,这些通配符又都是什么意思呢? 常用 T,E,K,V,?...car = operate(); 简单总结下: T 是一个 确定 类型,通常用于方法定义,?是一个 不确定 类型,通常用于方法调用代码和形参,不能用于定义方法。...对于通配符来说,因为它不是一个确定类型,所以不能进行多重限定。 区别3:通配符可以使用限定而类型参数不行 类型参数 T 只具有 一种 类型限定方式: T extends A 但是通配符 ?

    13910

    深入理解 Java

    名中声明参数类型后,内部成员、方法就可以使用这个参数类型,比如上面的 GenericClass 就是一个,它在名后声明了类型 F,成员、方法就可以使用 F 表示成员类型、方法参数/返回值都是...Java 中并不会产生这个问题。虚拟机中并没有类型对象,所有的对象都是普通。...如果我们想要让参数保留一个边界,可以给参数设置一个边界参数将会被擦除到第一个边界边界可以有多个),这样即使运行时擦除后也会有范围。...规则 参数类型只能是(包括自定义),不能是简单类型。 同一种可以对应多个版本(因为参数类型是不确定),不同版本实例是不兼容。...4.数组中不能使用 这可能是 Java 面试题中最简单一个了,当然前提是你要知道 Array 事实上并不支持,这也是为什么 Joshua Bloch 在 《Effective Java》一书中建议使用

    2.1K111
    领券