gpt4 book ai didi

java - 这三个参数化变量有何不同?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:12:41 26 4
gpt4 key购买 nike

给定 AGenericClass 声明如下:

public class AGenericClass<T> {
T subject;
public void setSubject(T subject) {
this.subject = subject;
}
}

变量abc之间有什么区别?

AGenericClass<String> a = new AGenericClass<>();
AGenericClass<?> b = new AGenericClass<String>();
AGenericClass c = new AGenericClass<String>();

a.setSubject("L"); // OK.

b.setSubject("M"); // Error: setSubject(capture<?>) cannot be
// applied to (java.lang.String)

c.setSubject("N"); // Warning: Unchecked call to 'setSubject(T)'
// as a member of raw type 'AGenericClass'

a bc 都是在 IDE 没有提示的情况下声明的,但是当 setSubject 被调用。

最佳答案

这三者之间的差异很大程度上与您在编译时获得的检查有关。鉴于泛型旨在保护用户免受运行时不安全转换的影响,因此它们之间的关键和主要差异就 Root 于此。


AGenericClass<String>声明类型为 String 的泛型类实例.使用此泛型完成的任何需要泛型参数的操作都会将该参数绑定(bind)到 String ,并将在编译时强制执行类型检查和类型安全。

也就是说,如果你有AGenericClass<String> a = new AGenericClass<>();你试着调用a.setSubject(3) , Java 将不允许应用程序编译,因为类型不匹配。

AGenericClass<?>声明具有未知 类型的泛型类的实例。正式地,?是一个通配符,它​​可以是任何类型,可以如果您想从中检索元素,但不是如果您想要从中添加元素。

原因是什么? AGenericClass<?>实际上是 AGenericClass<? extends Object> ,这很重要,因为 in and out principle .通常(虽然这不是严格保证),任何与 extends 通用的东西意味着只读操作。

正如我之前所说,从中读取很好,因为保证您的类(class)至多Object ,但是您不能写入它,因为您不知道,也不能保证,您从任何给定的调用中添加了什么样的对象。

AGenericClass 没有 类型声明是原始类型。 You can read more about them here ,但要知道它们的存在是出于遗留兼容性原因。如果您的代码使用原始类型,您将失去编译时检查并且您的代码可能最终会抛出 ClassCastException。在运行时,调试、诊断和解决要困难得多。

关于java - 这三个参数化变量有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36052041/

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