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

泛型返回类型上限-接口与类-令人惊讶的有效代码

施令雪
2023-03-14

这是一个来自第三方库API的真实示例,但经过了简化。

用Oracle JDK 8U72编译

考虑以下两种方法

<X extends CharSequence> X getCharSequence() {
    return (X) "hello";
}

<X extends String> X getString() {
    return (X) "hello";
}

两者都报告了一个“未经检查的强制转换”警告--我知道原因了。让我困惑的是为什么我可以打电话

Integer x = getCharSequence();
Integer y = getString();
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
<X extends CharSequence> void doCharSequence(List<X> l) {
}

List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles

List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error

试图传递列表 会出现错误,正如所料:

method doCharSequence in class generic.GenericTest cannot be applied to given types;
  required: java.util.List<X>
  found: java.util.List<java.lang.Integer>
  reason: inference variable X has incompatible bounds
    equality constraints: java.lang.Integer
    upper bounds: java.lang.CharSequence

如果报告为错误,为什么整数x=getCharSequence();不是?

共有1个答案

子车勇锐
2023-03-14

CharSequence是一个接口。因此,即使SomeClass没有实现CharSequence,也完全可以创建一个类

class SubClass extends SomeClass implements CharSequence

因此你可以写

SomeClass c = getCharSequence();

因为推断的类型X是交集类型SomeClass&CharSequence

<T extends Integer & CharSequence>
<T extends Integer & CharSequence> void foo(List<T> list) {
    doCharSequence(list);
}  

如果您有一个返回列表 的方法,如下所示:

static <T extends CharSequence> List<T> foo() 

你可以做

List<? extends Integer> list = foo();

同样,这是因为推断的类型是integer&charsequence,这是integer的子类型。

关于进一步的信息,这里是JLS中解释类型边界如何工作的部分。您可以包括多个接口,例如。

<T extends String & CharSequence & List & Comparator>

但只有第一个界限可以是非接口。

 类似资料:
  • 问题内容: 这是来自第三方库API的真实示例,但已简化。 与Oracle JDK 8u72一起编译 考虑以下两种方法: 两者都报告“未经检查的演员表”警告-我明白原因。让我感到困惑的是为什么我可以打电话 它可以编译吗?编译器应该知道没有实现。致电 给出错误(按预期) java.lang.Integer,java.lang.String 有人可以解释为什么将这种行为视为有效吗?有什么用? 客户端不知

  • 我正在尝试返回一个对象,它应该是IClass的一个实现,具有一个通用类型,是IType的一个实现。 我要返回的实际类扩展了Class (abstract ),其泛型类型为ActualType: 抽象类对象实现了IClass接口,可以有任何扩展IType的类型 ActualType只是实现了IType接口 我在编译时得到一个“类型不匹配:无法从ActualClass转换为IClass”错误。我不明白

  • 我在我的Java程序中写了这个函数: 这就是我所说的: 它是有效的,但我觉得我应该能够省略第一个参数,并从返回类型(结果被分配到的类型)推断出它。这可能吗?如果是,语法是什么?

  • 问题内容: 我正在玩Go,发现一个我无法解决的问题。假设我有如下代码: 我导入了软件包并开始使用它: 我真的很喜欢我的助手“运行”,但是我想使其更加慷慨:我不希望人们总是向我传递MySQL客户端。可以是具有“ RunQuery”和“ Result”方法的任何东西。所以我尝试使用接口: 可悲的是,这不再编译了。我收到此错误: Go不支持此功能吗,或者我做错了什么? 问题答案: 应该返回接口,否则你总

  • 谁能解释一下吗?

  • 对于一堆带有泛型的包装类,我的继承结构遇到了一些麻烦。这基本上是结构: 这将与当前代码一起编译和工作,但是,这似乎很危险。如果调用方像这样使用这个方法:,它将很好地编译,但是如果findMiddle尝试返回SubBWrapper,则在运行时会有一个ClassCastException。我以为行得通却行不通的是: 所以我的问题基本上是,有没有正确的方法来编写编译、运行并遵循最佳实践的方法findMi