Java Generics通配符扩展了最终类

L4z*_*4zy 10 java generics

为什么Java在编译my时不会抛出任何警告TestGenerics class,考虑到String class是否final且无法扩展?

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

ysh*_*vit 7

假设我有一个这样的方法:

public List<? extends T> filterOutNulls(List<T> input) { ...
Run Code Online (Sandbox Code Playgroud)

当然,这不是世界上最好的签名,但仍然完全合法.如果我传递List<String>给那个方法会发生什么?根据签名,它返回一个List<? extends String>.如果Java不允许使用该类型,则不可能使用此方法List<String>(或者至少不可能使用返回值).

其次,extends语法在这种情况下仍然有用,因为List<String>List<? extends String>有不同的限制 - 具体来说,除了null文字之外,你不能添加任何内容List<? extends String>.我有时会? extends用来表示一个集合是只读的(因为T你可以传入的唯一的是null),并且? super表示只写(因为你只能得到Ts Object).这不是完全万无一失的(你仍然可以调用删除方法,传入nulls ,传播,等等),但它可以温和地提醒你如何使用这个集合.


tbo*_*odt 6

编译器并没有真正注意到这一事实,因为它并不重要.String仍然允许在列表中,并且在最终产品中,String找不到任何扩展的可能性.后删除,它出来是这样的:

public void addStrings(List list)
Run Code Online (Sandbox Code Playgroud)

如您所见,现在没有类扩展的建议String.如果你确实创建了一个扩展类String,那将是一个编译错误.javac不需要担心这一点.

  • 通过这种推理,你应该能够将`List <Apple>`传递给一个期望`List <Orange>`的方法,因为在擦除之后它们都只是`List`.字节码肯定是正确的,但泛型的全部意义在于提供类型安全**超出*字节代码可以提供的内容. (3认同)