Java泛型中的Get put原则
我最近在学习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
我的问题是,据说您只能从使用
列表的引用类型的集合中获取对象。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()并不是被禁止的,这就解释了整个事情。谢谢