Java 泛型:如何使编译器控制我放入构造函数的类型
此示例取自Java中的ThinkingJava 泛型:如何使编译器控制我放入构造函数的类型,java,generics,Java,Generics,此示例取自Java中的Thinking public class Automobile { } public class Holder<T> { private T a; public Holder(T a){ this.a = a; } public void set(T a){ this.a = a; } public T get(){ return a; } p
public class Automobile {
}
public class Holder<T> {
private T a;
public Holder(T a){
this.a = a;
}
public void set(T a){
this.a = a;
}
public T get(){
return a;
}
public static void main(String[] args){
Holder<Automobile> h = new Holder<Automobile>(new Automobile());
Automobile a = (Automobile)h.get();
}
}
因此,正如我所看到的,编译器不会控制我放入Holder对象的内容。好吧,那我就不懂泛型了。我有两个问题:
泛型的要点是编写可以包含或处理任何对象的数据结构。您可以在使用时指定它应该包含哪些类型的对象,例如:
ArrayList<String> stringList = new ArrayList<String>();
ArrayList stringList=新建ArrayList();
(用于显示的Diamondoperator未简写)
回答以下问题:
1:编写能处理所有对象(如集合)的代码,是的,编译器理解并能在编译时检查代码
2:是的,不要使用泛型,而是为您的汽车编写代码规范
Holder<Automobile> h = new Holder<Automobile>(new Automobile());
Automobile a = (Automobile)h.get();
Holder h = new Holder(new Automobile());
Automobile a = (Automobile)h.get();
这是自java 1.5及以上版本以来最好的方法:
Holder<Automobile> h = new Holder<Automobile>(new Automobile()); //specify the generic parameter on both static and dynamic type
Automobile a = h.get(); //no casting is necessary
支架
我甚至不确定如果没有泛型,这是否可行:
因此,从技术上讲,泛型支持额外的特性,同时也鼓励类型安全性,从而减少代码错误,这总是很好的
Integer a = new Integer(6);
List<Integer> list = new ArrayList<Integer>();
list.add(a);
list.add("5"); //this will not compile -> you won't need to wait until runtime to see that things are incorrect!
整数a=新整数(6);
列表=新的ArrayList();
列表.添加(a);
列表。添加(“5”)//这将不会编译->您不需要等到运行时才能看到错误!
“这是自java 1.5及以上版本以来最好的做事方式:“我不得不不同意。您使用的是原始类型构造函数,这是不安全的。正确的方法是Holder h=新的Holder(new Automobile())代码>或(在Java 1.7+中<代码>支架h=新支架(新汽车())代码>。使用原始类型构造函数可以关闭泛型类型检查。假设Holder
的构造函数是publicholder(列表a)
,那么Holder h=newholder(newarraylist())代码>将被允许,即使它显然是错误的。@newacct绝对正确!很抱歉出错了,显然构造函数参数把我搞砸了。固定的。我添加了两条注释,java 1.7,还修复了第三个代码段中的一个错误,请在编辑后检查答案
Holder<Automobile> h = new Holder<Automobile>(new Automobile()); //specify the generic parameter on both static and dynamic type
Automobile a = h.get(); //no casting is necessary
Holder<Automobile> h = new Holder<>(new Automobile()); //diamond operator so you don't need to respecify the same thing
Automobile a = h.get();
Integer a = new Integer(6);
List list = new ArrayList();
list.add(a);
list.add("5");
for(int i = 0; i < list.size(); i++)
{
Integer integer = (Integer)list.get(i); //crashes at "5" which is String at runtime
System.out.println(integer);
}
Integer a = new Integer(6);
List<Integer> list = new ArrayList<Integer>();
list.add(a);
list.add("5"); //this will not compile -> you won't need to wait until runtime to see that things are incorrect!