简体   繁体   English

java Generics 通配符

[英]java Generics Wildcard

I have a question on the use of wildcards in Java's generic types: what is the basic difference between List<? extends Set>我有一个关于在 Java 的泛型类型中使用通配符的问题: List<? extends Set> List<? extends Set> and List<T extends Set> ? List<? extends Set>List<T extends Set> When would I use either?我什么时候用?

Two reasons:两个原因:

To avoid unnecessary casts:为避免不必要的强制转换:

You have to use the T variant for cases like this:对于这样的情况,您必须使用T变体:

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

With ?? this would become:这将变成:

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

...which doesn't give the same amount of information to the caller of the firstOf method. ...这不会为firstOf方法的调用者提供相同数量的信息。 The first version allows the caller to do this:第一个版本允许调用者这样做:

SubSet first = firstOf(listOfSubSet);

while with the second version, you are forced to use a cast to make it compile:而在第二个版本中,您必须使用强制转换来使其编译:

SubSet first = (SubSet)firstOf(listOfSubSet);

To enforce matching argument types:强制匹配参数类型:

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;
}

There is no direct equivalent using ?没有直接等效的使用? instead of T for this.而不是T Note that due to Java's single-dispatch, in the above version, the compiler will call at 's equals(T) method which may well differ from at 's equals(Set) or equals(Object) method.请注意,由于 Java 的单调度,在上述版本中,编译器将调用atequals(T)方法,这可能与atequals(Set)equals(Object)方法有很大不同。

The difference here is that in the second version, you have a type variable T that refers to the specific subtype of Set that the List contains.这里的不同之处在于,在第二个版本中,您有一个类型变量T ,它引用List包含的Set的特定子类型。 You need this in cases where you need to ensure that something else is the same type as the type contained in the list.在需要确保其他内容与列表中包含的类型相同的情况下,您需要这样做。 A couple simple examples:几个简单的例子:

// 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) {
  ...
}

Simple rule: Use a type variable T extends Foo in your method signature if the same type is necessary in two places.简单规则:如果在两个地方需要相同的类型,则在方法签名中使用类型变量T extends Foo Method parameters are each one place and the method return type is another place.方法参数在一个地方,方法返回类型在另一个地方。 Use the wildcard ? extends Foo使用通配符? extends Foo ? extends Foo if you just need to ensure you're dealing with "something that is a Foo " in one place. ? extends Foo如果您只需要确保在一个地方处理“某物是Foo ”。

Aside: don't use the raw type Set .另外:不要使用原始类型Set

You use List<? extends Set>你使用List<? extends Set> List<? extends Set> when you declare a varlable. List<? extends Set>当你声明一个变量时。 For example:例如:

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

List<T extends Number> can be used in class or methode declaration. List<T extends Number>可以在 class 或方法声明中使用。 This will allow you to write T instead of <? extends Number>这将允许您写 T 而不是<? extends Number> <? extends Number> later on in the function. <? extends Number>稍后在 function 中。

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

We use wildcards to specify that the type element matches anything.我们使用通配符来指定类型元素匹配任何内容。 The ? ? stands for unknown type.代表未知类型。

List<? extends Set> List<? extends Set> is an example of a bounded wildcard and that states that the list can accept any subtype of a Set (eg HashSet ) List<T extends Set> , on the other hand is, allows T to be bounded to a type that extends Set . List<? extends Set>是有界通配符的一个示例,它声明列表可以接受Set任何子类型(例如HashSetList<T extends Set>另一方面是允许T绑定到扩展的类型Set

I use wildcards when I need a collection of data irrespective pf it's exact type.当我需要数据集合时,我使用通配符,而不管它的确切类型。

A wildcard type G<? extends A>通配符类型G<? extends A> G<? extends A> is a super type of any G<Ai> where Ai is a subtype of A G<? extends A>是任何G<Ai>的超类型,其中AiA的子类型

In another word, G<? extends A>换句话说, G<? extends A> G<? extends A> is the union type of G<A0>, ..., G<An> . G<? extends A>G<A0>, ..., G<An>的联合类型。

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

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