Java泛型中的Get put原则

Java泛型中的Get put原则,java,generics,overriding,bounded-wildcard,Java,Generics,Overriding,Bounded Wildcard,我最近在学习Java泛型,遇到了所谓的“get-put”原则,即哪种通配符允许您从集合中添加或删除某些类型的对象(例如引用) 我的问题是,据说您只能从使用列表的引用类型的集合中获取对象。get()在本例中是对象,该类声明toString(),因此您可以调用它 但是Java使用它来选择要执行的方法。由于对象的运行时类型是A,因此调用的是该版本 您的代码与此等效: Object obj = new A(); System.out.println(obj.toString()); /* Prints

我最近在学习Java泛型,遇到了所谓的“get-put”原则,即哪种通配符允许您从集合中添加或删除某些类型的对象(例如引用)


我的问题是,据说您只能从使用
列表的引用类型的集合中获取对象。get()
在本例中是
对象,该类声明
toString()
,因此您可以调用它

但是Java使用它来选择要执行的方法。由于对象的运行时类型是
A
,因此调用的是该版本

您的代码与此等效:

Object obj = new A();
System.out.println(obj.toString()); /* Prints A's version */
A a = obj; /* Fails to compile. */

如您所见,该行为与泛型无关。

在本例中,
list.get()
的引用类型是
Object
,该类声明了
toString()
,因此您可以调用它

但是Java使用它来选择要执行的方法。由于对象的运行时类型是
A
,因此调用的是该版本

您的代码与此等效:

Object obj = new A();
System.out.println(obj.toString()); /* Prints A's version */
A a = obj; /* Fails to compile. */

如您所见,该行为与泛型无关。

这里没有发生意外情况。让我们完成以下步骤:

List<? super A> list = new ArrayList<>();
到目前为止,所有良好的
列表
内部都有一个
A
,它作为
对象
获取

                               .toString()));
我们调用
toString
,它是在
对象上调用的(
A
)。动态分派继续调用
A
toString
方法(类型层次结构中的最低定义)。但是,这是完全合法的,因为
toString
是为
对象以及
A
定义的。继续

 A a = list.get(0); //oops!

正如预期的那样,这会中断,因为我们试图将
对象
列表
转换为
a
,而不使用强制转换(例如
a=(a)List.get(0);
)。

这里没有发生意外情况。让我们完成以下步骤:

List<? super A> list = new ArrayList<>();
到目前为止,所有良好的
列表
内部都有一个
A
,它作为
对象
获取

                               .toString()));
我们调用
toString
,它是在
对象上调用的(
A
)。动态分派继续调用
A
toString
方法(类型层次结构中的最低定义)。但是,这是完全合法的,因为
toString
是为
对象以及
A
定义的。继续

 A a = list.get(0); //oops!

正如预期的那样,这会中断,因为我们试图将
对象
列表
转换为
a
,而不使用强制转换(例如
a=(a)List.get(0);
)。

但为什么编译器不抱怨我尝试访问下限集合,正如书中所说的那样?@AvramPop我不理解你的问题。你能指出书中说的哪一行代码应该是编译错误吗?System.out.println((list.get(0.toString());-应该禁止从下界泛型获取。@AvramPop如果你的书上说这是禁止的,那就错了。您可以调用泛型类型的任何(可访问)方法;下限不会神奇地使以前可调用的方法无法调用。这本书应该说的是结果的类型是未绑定的。您只知道它是一个
对象
(因为所有类都扩展了
对象
)。我认为这句话是指你所发现的:
A=list.get(0)
不起作用,但这是因为
list.get(0)
的结果的编译时类型是
Object
,而不是
A
,这并不是因为
get()
是被禁止的。我认为问题在于对概念的正确理解——您所说的get()并不是被禁止的,这就解释了整个事情。谢谢,但为什么编译器不抱怨我试图访问下限集合,正如书中所说的那样?@AvramPop我不理解你的问题。你能指出书中说的哪一行代码应该是编译错误吗?System.out.println((list.get(0.toString());-应该禁止从下界泛型获取。@AvramPop如果你的书上说这是禁止的,那就错了。您可以调用泛型类型的任何(可访问)方法;下限不会神奇地使以前可调用的方法无法调用。这本书应该说的是结果的类型是未绑定的。您只知道它是一个
对象
(因为所有类都扩展了
对象
)。我认为这句话是指你所发现的:
A=list.get(0)
不起作用,但这是因为
list.get(0)
的结果的编译时类型是
Object
,而不是
A
,这并不是因为
get()
是被禁止的。我认为问题在于对概念的正确理解——您所说的get()并不是被禁止的,这就解释了整个事情。谢谢