简体   繁体   English

Java Generics通配符扩展了最终类

[英]Java Generics wildcard extends final class

Why does Java doesn't throw any warning when compiling my TestGenerics class , considering that the String class is final and cannot be extended? 为什么Java在编译我的TestGenerics class时不会抛出任何警告,因为String classfinal并且无法扩展?

import java.util.*;
    public class TestGenerics { 
        public void addStrings(List<? extends String> list) {
          // some code here
        }
    }
}

Let's say I had a method like this: 假设我有一个这样的方法:

public List<? extends T> filterOutNulls(List<T> input) { ...

Granted, not the best signature in the world, but still perfectly legal. 当然,这不是世界上最好的签名,但仍然完全合法。 What would happen if I passed a List<String> to that method? 如果我将List<String>传递给该方法会发生什么? According to the signature, it returns a List<? extends String> 根据签名,它返回一个List<? extends String> List<? extends String> . List<? extends String> If Java disallowed that type, it'd be impossible to use this method for List<String> (or at least, it'd be impossible to use the return value). 如果Java不允许使用该类型,则不可能将此方法用于List<String> (或者至少,不可能使用返回值)。

Secondarily, the extends syntax is still useful in this case, since List<String> and List<? extends String> 其次,在这种情况下, extends语法仍然有用,因为List<String>List<? extends String> List<? extends String> have different restrictions -- specifically, you can't add anything but a null literal to List<? extends String> List<? extends String>有不同的限制 - 具体来说,你不能向List<? extends String>添加除null文字之外的任何内容List<? extends String> List<? extends String> . List<? extends String> I'll sometimes use ? extends 我有时会用? extends ? extends to signify that a collection is read-only (since the only T s you can pass in are null ), and ? super ? extends表示集合是只读的(因为你可以传入的唯一Tnull ),并且? super ? super to signify write-only (since you can only get out T s as Object ). ? super表示只写(因为你只能将T s作为Object )。 This isn't completely fool-proof (you can still call remove methods, pass in null s, downcast, etc) but serves as a gentle reminder of how the collection is probably meant to be used. 这不是完全万无一失的(你仍然可以调用remove方法,传入null s,downcast等),但它可以温和地提醒你如何使用这个集合。

The compiler doesn't really take note of that fact, because it doesn't matter. 编译器并没有真正注意到这一事实,因为它并不重要。 String s are still allowed in the list, and in the final product, the possibility of anything extending String is not found. String仍然允许在列表中,并且在最终产品中,找不到任何扩展String的可能性。 After erasure , it comes out like this: 擦除后 ,它出现如下:

public void addStrings(List list)

As you can see, there is now no suggestions of a class extending String . 如您所见,现在没有关于扩展String的类的建议。 If you do create a class extending String , that will be itself a compile error. 如果你确实创建了一个扩展String的类,那么它本身就是一个编译错误。 There's no need for javac to worry about that. javac不需要担心这一点。

The type system does not consider List<String> and List<? extends String> 类型系统不考虑List<String>List<? extends String> List<? extends String> equivalent, even though at the time of compiling, String has no subtypes other than itself, therefore any object that is a List<? extends String> List<? extends String> equivalent,即使在编译时, String没有自身以外的子类型,因此任何对象都是List<? extends String> List<? extends String> must also be a List<String> . List<? extends String>也必须是List<String>

One explanation is that final is not final - it's ok to remove final from a class and nothing should break: http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.2 一种解释是, final不是最终的 - 可以从类中删除final并且没有任何内容可以破解: http//docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls- 13.4.2

It's not without precedence that the type system takes final into consideration; 并不是没有优先考虑类型系统final考虑; for example, we cannot cast a String to a Runnable , because the compiler figures that if an object is String , it cannot be some unknown subclass that implements Runnable . 例如,我们不能将一个String转换为Runnable ,因为编译器认为如果一个对象是String ,它不能是一个实现Runnable未知子类。

If we want generics also to make reasoning like that and deduce that List<String> and List<? extends String> 如果我们希望泛型也能像这样推理并推导出List<String>List<? extends String> List<? extends String> are equivalent, it'll make typing rules even more complicated. List<? extends String>是等价的,它会使输入规则更加复杂。

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

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