考虑下面的示例代码
/* The new Java 5 or later Generic code */
class TestInserter {
public static void main(String[] ar) {
List<Integer> myList = new ArrayList<Integer>();
myList.add(20);
myList.add(42);
Inserter ins = new Inserter();
ins.insert(myList);
}
}
/* Legacy Code */
class Inserter {
public void insert(List list) {
list.add(new Integer(55));
}
}
编译并执行上面的代码将运行得很好,没有编译器或JVM的任何抱怨。 non type-safe
insert()方法在我们的type-safe
ArrayList中插入一个新的Integer对象。但是,如果我将insert方法更改为以下内容:
public void insert(List list) {
list.add(new String("55"));
}
说什么?!上面的代码会运行吗?考虑一下,确定它会运行,奇怪但是上面的代码编译并运行得很好。 这与Arrays略有不同,它为您提供编译时和运行时保护,并防止此类事件发生。他们为什么这样做泛型?为什么Java允许泛型放入指定类型以外的值?!
答案 0 :(得分:1)
现在回答。使用insert
方法将Integer
添加到列表中是非常安全和可允许的,因为它与我们为myList
变量指定的类型相匹配。但是,当我们尝试将String
插入到仅包含ArrayList
值的Integer
时,则会出现问题,不是在编译时,而是在运行时,当您尝试在错误添加的Integer
实例上调用String
特定方法时。
为了理解整个问题及其目的,您应该理解一件事 - JVM不知道您试图将String
插入ArrayList
意味着只保留Integer
s。所有的泛型及其类型安全性仅限编译时间。通过名为&#34; 类型擦除&#34;的过程,编译器从通用代码中删除所有类型参数。换句话说,即使你写了这样的东西:
List<Integer> myList = new ArrayList<>();
在编译器完成之后成为以下代码:
List myList = new ArrayList();
然而,他们为什么要像这样保留泛型?
答案很简单!如果它不会出现这种奇怪的行为,那么早期Java版本的遗留代码就会被破坏,而且Million Java开发人员必须编辑Trilions的旧Java代码才能使其再次运行!!
但不要责怪编译器;当您尝试运行代码时,编译器会尝试使用以下警告警告您:
$> javac TestInserter.java
Note: TestInserter.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
当你按照编译器要求的方式执行操作时如下:
$> javac -Xlint:unchecked TestInserter.java
TestInserter.java:15: warning: [unchecked] unchecked call to add(E) as a member of the raw type List
list.add(new String("55"));
^
where E is a type-variable:
E extends Object declared in interface List
1 warning
就编译器而言,它试图告诉您它怀疑程序中的某些代码可能最终遇到麻烦。
要将其包装起来,将泛型视为编译时保护。编译器使用类型信息(参数中指定的类型)来确保您不会将错误的内容插入集合(或用户定义的泛型类型),并且您不会从错误中获取值参考类型。 所有通用保护都是编译时间!这就是它。
答案 1 :(得分:0)
编译时泛型几乎涵盖了需要泛型类型断言的所有情况。对于需要在运行时泛型类型安全性中进行设计的极少数情况,您可以存储运行时类型标记(RTTT),Class<T>
的实例,其中{{1}是通用参数。
T
除了你大部分时间都不需要运行时泛型之外,Java在引入泛型时遇到了问题。使它们的运行时可执行(“可恢复”)将破坏一堆遗留代码或使语言变得非常复杂。默认情况下,使用泛型编译时,允许遗留代码以原始类型的形式存在,并且仍与更好编写的代码共存。
那里有一个妥协的元素,比如写原始类型的诱惑。不要那样做。我们有时不得不围绕未经检查的转换跳舞。但它几乎总能完成工作。