当前位置: 首页 > 知识库问答 >
问题:

为什么Java泛型允许通配符的上限高于类型参数的通配符?

司空高义
2023-03-14

这是我试图理解的编译器行为的一个过度简化版本:

class Scratch {
    public static void main(String[] args) {
        HouseCat<? extends Mammal> hcat = new Tabby();
        //HouseCat<Mammal> won't work, compiler catches incorrect type parameter bound
        HouseCat<CrazyHouseCat> crazyCat = new Tabby();
    }
}

interface Mammal<T extends Mammal> extends Comparable<T>{
    T cloneInstance();
}

interface Feline<T extends Feline> extends Mammal<T>{}    

interface HouseCat <T extends HouseCat> extends Feline<T>{}

interface CrazyHouseCat<T extends CrazyHouseCat> extends HouseCat<T>{
    void pushStuffOverTvStand();
}

class Tabby implements CrazyHouseCat<CrazyHouseCat>{

    @Override
    public CrazyHouseCat cloneInstance() {
        return null;
    }

    @Override
    public void pushStuffOverTvStand() {

    }

    @Override
    public int compareTo(CrazyHouseCat o) {
        return 0;
    }
}

在上面的代码片段中,housecat<?extends Mammal>是一个类型范围比HouseCat接口允许的类型范围更广的引用,即:HouseCat

如果我尝试执行类似housecat 的操作,编译器会告诉我long不满足类型参数的约束。那么,<不是吗?扩展mammal>,至少是潜在的。

编译器不会让我创建违反类型参数t约束的实例,但我对它使用mammal作为引用上限的行为感到困惑。在(housecatmammal)之间有一个无效的类型范围,那么编译器为什么不拒绝这个引用定义呢?

澄清:我的问题不是关于通配符的含义?。我在问为什么编译器允许使用比参数化类型定义更广泛的类型来定义对参数化类型实例的引用。上面提到的问题并不是针对这个特定的情况,而是关于通配符的含义。我的问题是通配符的有效范围,编译器似乎没有强制执行。

共有1个答案

权浩阔
2023-03-14

这看起来回答了你的问题。基本上housecat<?extends Mammal>允许创建HouseCat<[在此处插入扩展Mammal的类型]>。全部<代码><?extends Mammal>做为泛型。在你的例子中,我不明白你为什么要尝试这样做,但我希望这能有所帮助。

 类似资料:
  • 问题内容: 我正在刷新有关Java泛型的知识。因此,我转向了Oracle的优秀教程……并开始为我的同事编写一个演示文稿。我在本教程中遇到了有关通配符的部分,内容为: 考虑以下方法,printList: printList的目标是打印任何类型的列表,但未能实现该目标- 它仅打印Object实例的列表;它不能打印,,,等等,因为它们不是的亚型。要编写通用的printList方法,请使用: 我知道那是行

  • 我正在刷新我关于Java泛型的知识。所以我转向甲骨文的优秀教程...并开始为我的同事准备一个演示文稿。我在教程中遇到了通配符部分,上面写着: 考虑以下方法,打印列表: printList的目标是打印任何类型的列表,但它无法实现该目标-它只打印对象实例的列表;无法打印列表 我明白那个

  • 问题内容: 我试图理解Java泛型,它们似乎很难理解。例如,这很好… …就是这个… … 还有这个 … …但是不能编译: 有人可以用简单的语言解释发生了什么吗? 问题答案: 对于泛型类型,主要要了解的是它们不是协变的。 因此,尽管您可以这样做: 以下内容将无法编译: 这是为了避免您绕过通用类型的情况: 因此,一一讲解您的示例 1个 您的通用方法采用a ,而您采用;(基本上是)。可以分配给类型,并且编

  • 问题内容: 我试图了解下限和上限通配符的行为。 尝试编译以下代码时遇到问题。 为了弄清楚问题,我还尝试了下限通配符。幸运的是或不幸的是,代码可以很好地编译,但是却造成了很多混乱。 有人可以解释一下这两个代码段如何工作。如果有人可以提供其他示例/链接,那就太好了。 如果我在上面做错了什么,请纠正我。 提前致谢。 问题答案: 表示“未知类型”。 表示某种对象的集合。此“某种类型”可以是作为其子类或自身

  • 问题内容: 我认为,由于类型擦除,使用和不允许的除外。为什么Java语言设计人员允许此异常?对于无限制的通配符类型,类型擦除没有任何作用吗? 问题答案: 关键是对象知道其具体类,但不知道其通用类型参数。因此,如果我们构造一个,则在执行时就知道它是 某种 类型的-但它不知道该部分。 “ 某种”部分恰好意味着什么,这就是为什么: 已验证。这等效于使用原始类型:

  • 问题内容: 我对Java中的通用通配符有两个疑问: 和之间有什么区别? 什么是有界通配符,什么是无界通配符? 问题答案: 在你的第一个问题中,并且是有界通配符的示例。无限制的通配符看起来像,基本上就是<? extends Object>。宽松地表示泛型可以是任何类型。有界通配符(或)通过说它必须扩展特定类型(称为上限)或必须是特定类型的祖先(称为下限)来对类型进行限制。