jdk1.5提供的泛型好像有bug哦,请看下面的程序:
import java.util.ArrayList;
import java.util.List;public class TryGeneric
{
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(1);
list.add(2);
new MyGeneric().printAll(list);
}
}class MyGeneric<K,T>
{
public void printAll(List<String> list)
{
}
}printAll方法的参数是List<String>型的,可为什么我还是可以把List<Integer>的引用传入呢?
import java.util.ArrayList;
import java.util.List;public class TryGeneric
{
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(1);
list.add(2);
new MyGeneric().printAll(list);
}
}class MyGeneric<K,T>
{
public void printAll(List<String> list)
{
}
}printAll方法的参数是List<String>型的,可为什么我还是可以把List<Integer>的引用传入呢?
解决方案 »
- 怎么提交数据哦?
- 跪求几张素材图片……
- 用java访问windows的AD的问题。急!!!帮顶也有分!!
- java与SQLSERVER连接问题
- 两个多线程socket之间的监听问题
- 一个小小问题(out.println的问题)
- c语言和java赋值的区别
- java下怎么就任意的随机数?random怎么用啊?
- 刚下载jb5,我想要快速入门,请大虾花最少的时间解答但对YOU是小菜的问题?请用具体的操作教我做一个简单的数据库应用。当然只是说步鄹(从新建项目到打包运性,一定要详细罗,)代码不必了。
- JAVA线程命名不成功
- spring 初学问 惭愧
- *.java 使用了未经检查或不安全的操作是什么意思?
答非所问罗。
import java.util.List;public class Test
{
public static void main(String[] args) {
List<Integer> inte = new ArrayList();
List<String> stri = new ArrayList();
System.out.println(inte instanceof List);//list的一个实例
System.out.println(stri instanceof List);//list的一个实例
System.out.println(inte.getClass().getName());//类名:Arraylist
System.out.println(stri.getClass().getName());//类名:Arraylist
System.out.println(inte.getClass()==stri.getClass());//同一个类
}
}因为是同一个类,互相传递当然没有问题··但是当你把一个Integer类型list的传到Sting型list后,get就会报错···
{
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(1);
list.add(2);
new MyGeneric().printAll(list);
}
}
list.add(1);
list.add(2);
有问题应该是:
list.add(new Integer(1));
list.add(new Integer(2));
比如,我们以前要用((String)list.get(0)).charAt(0);
现在有了List<String)我们就可以直接使用list.get(0);
在底层的实现中,jre其实还是使用了动态类型转变,只是在编译的时候就检查过了,确定这个转变是正确的。而当你把Product变成Product<T>的时候,这个Product<T>成为了范型。Product这个东西叫做原始形态。而你上面使用了new Product(),编译器本来需要检查这个T,而你并没有提供,这个Product<T>就又成了原始形态,理所当然的,这个范型中的prt(List<String>) 在你使用new Product().prt(list)的时候,也被编译器认做了原始形态。请注意,如果你改成 public void prt(List<String> l) {
l.get(0).charAt(0);
System.out.print(l);
}l.get(0).charAt这行编译器不会有警告。你或许会问,为什么被打回了原始形态,编译器还会承认这行呢?不是应该使用 ((String)l.get(0)).charAt么?那是因为这行本身并没有任何错误。这个类在使用正确的前提下是完全正确的。而你出错的地方在new Product().prt(list);
所以,编译器只会在编译这行的时候使用这个范类的原始形态
{
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(new Integer(1));
list.add(new Integer(2));
new MyGeneric().printAll(list);
}
}class MyGeneric
{
public void printAll(List<? extends Integer> list)
{
}
}
java的泛型差c#差远了.
import java.util.List;public class TryGeneric
{
public static void main(String[] args) {
//原来的
//List<Integer> list = new ArrayList();
//修改后的
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
new MyGeneric().printAll(list);
}
}class MyGeneric<K,T>
{
public void printAll(List<String> list)
{}
}这样一改,你再试试看呢,相信大家都知道我说的是什么意思了,不再多讲废话了
------------------------------------------------------------------------
呵呵,谢谢kezhu2003(炎阳天) 兄的解答,但即便我不用泛型来定义一个类,在其中的方法中使用泛型来进行类型限制,也还是可以的,如果就因为使用了泛型就不可以了,我还是认为这是java泛型设计的不合理之处。
------------------------------------------------------------------------So, shouldn't this be an error? Theoretically speaking, yes; but practically speaking, if generic code is going to call legacy code, this has to be allowed. It's up to you, the programmer, to satisfy yourself that in this case, the assignment is safe because the contract of getAssembly() says it returns a collection of Parts, even though the type signature doesn't show this.
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode, sharing)C:\Documents and Settings\Shutrazh>javac TryGeneric.java
注意:TryGeneric.java 使用了未经检查或不安全的操作。
注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。C:\Documents and Settings\Shutrazh>javac -Xlint:unchecked TryGeneric.java
TryGeneric.java:7: 警告:[unchecked] 未经检查的转换
找到: java.util.ArrayList
需要: java.util.List<java.lang.Integer>
List<Integer> list = new ArrayList();
^
TryGeneric.java:11: 警告:[unchecked] 对作为普通类型 MyGeneric 的成员的 printAll
(java.util.List<java.lang.String>) 的调用未经检查
new MyGeneric().printAll(list);
^
2 警告
创建对象的时候带上 泛型,是可以检查出pringAll(list);的错误的。
而且楼主的程序
在这样实现printAll()方法,并运行时,会抛一个类型转换异常。
java.lang.ClassCastException: java.lang.Integer但是我这个结果并没有解决楼主的问题
--------------------------------------------------------
因为是“普通”类,所以编译器不会把泛型的作用域设定为整个类,如果类中有使用到泛型的方法,那编译器自然会使用泛型规则来进行验证。如果这个 method 是定义在一个泛型的 class 里的话,编译器就不报错了,这就是编译器的疏漏了,它完全有能力报个错出来,而且这种情况也不属于“向旧版本程序妥协”的范围呀。
--------------------------------------------------------
但是,如果是“泛型”类,编译器就会把泛型的作用域设定为整个类,如果在声明对象时没有应用泛型说明,编译器就认为程序员不使用新的泛型功能,以至于类中使用到泛型的方法也会被忽略。new MyGeneric().printAll(list);// 泛型被忽略
new MyGeneric<Class1, Class2>().printAll(list);// 泛型被采用,这时候list的类型要与printAll中的类型完全匹配
import java.util.List;public class TryGeneric
{
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
printAll(list);
}
static public void printAll(List<String> list)
{
}
}
这样写就会报错了。
如果象你那样把方法放在另一个类中是不会报错的。
原因如下:
如果你放在一个类中 编译器当然要先检查下用户定义的范行和使用方法的范行是匹配的 否者报错。
如果你放在两个类中,类检查前则必须先编译,大家应该知道类型擦除吧。结果
List<Object> list = new ArrayList();
public void printAll(List<Object> list);
都要用Object类 代替用户所写的规定类型。
这时候编译器再检查 就检查不出问题了,因为都是Object了(其实还是有别的方法可以来限制T的 不过默认的话就是转成Object类的,不过你这没用到)他会给出一个警告也就是下面这个
注意: F:\work\mywork\TEST\TryGeneric.java 使用了未经检查或不安全的操作。
注意: 要了解详细信息,请使用 -Xlint:unchecked 重新编译。Process completed.接下来检查这步骤只能用户来负责了;SUN 公司之所以把编译器做成这样目的是为了能够与范行以前的代码兼容,因此不要把他认为是类型擦除是正常程序的一部分,以为它本身就是个冒险的尝试
是泛型吗?
好好看看。