繁体   English   中英

java Generics 通配符

[英]java Generics Wildcard

我有一个关于在 Java 的泛型类型中使用通配符的问题: List<? extends Set> List<? extends Set>List<T extends Set> 我什么时候用?

两个原因:

为避免不必要的强制转换:

对于这样的情况,您必须使用T变体:

public <T extends Set> T firstOf(List<T> l) {
    return l.get(0);
}

? 这将变成:

public Set firstOf2(List<? extends Set> l) {
    return l.get(0);
}

...这不会为firstOf方法的调用者提供相同数量的信息。 第一个版本允许调用者这样做:

SubSet first = firstOf(listOfSubSet);

而在第二个版本中,您必须使用强制转换来使其编译:

SubSet first = (SubSet)firstOf(listOfSubSet);

强制匹配参数类型:

public <T extends Set> boolean compareSets(List<T> a, List<T> b) {
    boolean same = true;
    for(T at : a) {
        for (T bt: b) {
             same &= at.equals(bt);
        }
    }
    return same;
}

没有直接等效的使用? 而不是T 请注意,由于 Java 的单调度,在上述版本中,编译器将调用atequals(T)方法,这可能与atequals(Set)equals(Object)方法有很大不同。

这里的不同之处在于,在第二个版本中,您有一个类型变量T ,它引用List包含的Set的特定子类型。 在需要确保其他内容与列表中包含的类型相同的情况下,您需要这样做。 几个简单的例子:

// want to ensure that the method returns the same type contained in the list
public <T extends Set> T something(List<T> list) {
  ...
}

// want to ensure both lists contain the exact same type
public <T extends Set> List<T> somethingElse(List<T> first, List<T> second) {
  ...
}

简单规则:如果在两个地方需要相同的类型,则在方法签名中使用类型变量T extends Foo 方法参数在一个地方,方法返回类型在另一个地方。 使用通配符? extends Foo ? extends Foo如果您只需要确保在一个地方处理“某物是Foo ”。

另外:不要使用原始类型Set

你使用List<? extends Set> List<? extends Set>当你声明一个变量时。 例如:

List<? extends Number> l = new ArrayList<Integer>();

List<T extends Number>可以在 class 或方法声明中使用。 这将允许您写 T 而不是<? extends Number> <? extends Number>稍后在 function 中。

public <T extends Number> int addAll(List<T> list) {
    int result = 0;
    for (T t : list) {
        result += t.intValue();
    }
    return result;
}

我们使用通配符来指定类型元素匹配任何内容。 ? 代表未知类型。

List<? extends Set> List<? extends Set>是有界通配符的一个示例,它声明列表可以接受Set任何子类型(例如HashSetList<T extends Set>另一方面是允许T绑定到扩展的类型Set

当我需要数据集合时,我使用通配符,而不管它的确切类型。

通配符类型G<? extends A> G<? extends A>是任何G<Ai>的超类型,其中AiA的子类型

换句话说, G<? extends A> G<? extends A>G<A0>, ..., G<An>的联合类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM