gpt4 book ai didi

java - 泛型:如何让编译器控制我放入构造函数中的类型

转载 作者:行者123 更新时间:2023-12-01 12:46:23 24 4
gpt4 key购买 nike

这个例子取自Thinking in Java。

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

然后是解释:您必须使用与 main() 中看到的相同的尖括号语法来指定要放入其中的类型。

呃,我什么都听不懂。我理解,如果违反此规则,则必须将其视为可能的编译时错误。

但这有效:

    Holder<Automobile> h = new Holder(new Automobile());
Automobile a = h.get();

这有效:

Holder h = new Holder(new Automobile());
Automobile a = (Automobile)h.get();

因此,正如我所看到的,编译器不会控制我放入 Holder 对象中的内容。好吧,那么我根本就不懂泛型。我有两个问题:

  1. 使用它们的原因是什么?只是为了在将对象转换回汽车时节省一些精力?

  2. 有没有办法让编译器控制我,让我真的把 Automobile 放入 Holder 中?

最佳答案

这里的转换是不必要的:

    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

或者为简单起见,java 1.7 以上:

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

正如你所看到的,如果你可以无限制地将 Object 的任何子类放入列表中,那么你需要显式转换,如果你将任何不是你期望的东西放入列表中,那么它就会崩溃。请注意,如果没有泛型,您也不会被告知您应该将什么类型放入列表中,这意味着您需要跟踪列表应该包含的内容,当您尝试这样做时,这真的很糟糕逻辑如下:Java generics and casting to a primitive type

我什至不确定如果没有泛型,这是否可能: Is it possible to cast Map<Field, Value> to Map<Mirror, Mirror> when it is known that Field and Value extend Mirror?

因此,从技术上讲,泛型可以实现额外的功能,同时也鼓励类型安全,从而实现无错误的代码,这总是好的。

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!

关于java - 泛型:如何让编译器控制我放入构造函数中的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24660622/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com