java raw types,Java:Raw Types vs. Generics

Consider the sample code below

/* The new Java 5 or later Generic code */

class TestInserter {

public static void main(String[] ar) {

List myList = new ArrayList();

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

}

}

Compiling and executing the above code will run just fine, without any complaints from the compiler or the JVM. The non type-safe insert() method is inserting a new Integer object in our type-safe ArrayList. However, if I change the insert method to something like this:

public void insert(List list) {

list.add(new String("55"));

}

What say?! will the above code run? Think about it, Yes sure it will run, Strange but yes the above code compiles and runs just fine.

This is a little different from Arrays, which gives you both compile time and run time protection and prevents such things to happen. Why did they do Generics this way? Why does Java allows Generics to put in a value other than the specified type?!

解决方案

Now for the answer. Using the insert method to add an Integer to our list is quite safe and permissible, as it matches the type we have specified for our myList variable. But when we try to insert a String into an ArrayList that was meant to hold only Integer values, then there is a problem, not at compile time but at runtime, when you try to invoke an Integer-specific method on your wrongly added String instance.

There is one thing you ought to understand in order to understand this entire question and its purpose - The JVM has no idea that you were trying to insert a String into an ArrayList meant to hold only Integers. All your generics and their type-safety are restricted to compile time only. Through a process called "type erasure", the compiler removes all of the type parameters from the generic code. In other words, even though you wrote something like this:

List myList = new ArrayList<>();

Becomes the following after the compiler is done with it:

List myList = new ArrayList();

However, why did they keep Generics like this?

The answer is simple! If it wouldn't have been for this weird behavior then the legacy code from earlier versions of Java would have been broken and Million Java developers would have to edit Trillions of their old Java code to make it work again!!

But don't blame the compiler; when you try to run the code, the compiler tries to warn you with the following warning:

$> javac TestInserter.java

Note: TestInserter.java uses unchecked or unsafe operations.

Note: Recompile with -Xlint:unchecked for details.

And when you do as the compiler asks you to do as follows:

$> 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

As far as the compiler is concerned, it tries to tell you that it suspects that some code in your program might end up in trouble.

To wrap it up, Think of generics as just compile time protection. The compiler uses the type information (Type specified in parameter) to make sure that you don't insert the wrong things into a collection (or a user defined generic type) and that you don't fetch values from the wrong reference type. All of the generic protection is compile time! That's it for this.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值