我正在研究Java集合。 我发现了一些奇怪的事情并没有弄清楚为什么会这样。 所以这就是场景。
ArrayList al = new ArrayList();
al.add("Hello World");
//The below line is creating some confusion
System.out.print(al.get(0));
现在最后一行是印刷" Hello World"原样。
但由于我没有使用任何类型参数,它应该给出一个返回的对象类型。所以它应该调用对象的toString()
而不是字符串的toString()
。
它是否依赖于返回类型(如Object)保存的对象类型(如此处为String)。 请帮忙。
答案 0 :(得分:1)
如果您想从集合中返回String
,则必须使用String
类型参数对其进行初始化:
ArrayList<String> al = new ArrayList<String>();
// ^^^^^^^^ ^^^^^^^^
al.add("Hello World");
String value = al.get(0); //<-- now you can get Strings
现在,您只能获取对象,并且在返回原始类型之前必须进行投射:
ArrayList al = new ArrayList();
al.add("Hello World");
Object object = al.get(0); //<-- ok
String value = (String)al.get(0); // <-- ok
value = al.get(0); //<-- wont compile
修改强>
ArrayList al = new ArrayList();
al.add("Hello World");
Object object = al.get(0); //<-- ok
String value = object.toString();
在这种情况下,调用object.toString()
只会将对象作为String
返回。它将调用String
类上的toString
方法,该类只返回自身。
答案 1 :(得分:1)
调用对象的方法时,调用的实际方法是对象的实际类型。这就是为什么实际调用的toString是String类方法。
BTW:泛型类型用于编译时,而不用于运行时。例如,您不能在同一个类2中使用以下方法: void foo(List l)和 void foo(List l)因为编译后两者都有相同的签名。
答案 2 :(得分:1)
实际上所有技巧都与泛型有关,即使你的代码片段展示了它。
它与 overriden 方法有关,toString()
在超级超级类Object
中定义,并在String
类中覆盖,在运行时使用它们进行评估实际的对象类型而不是它的引用,即在调用时:
Object o = new String("hello");
o.toString(); // Here at runtime, the JVM will call the "hello" toString method and not the Object one.
在您的代码中,您已致电:
al.add("Hello World");
以上行执行以下操作:
String
对象,并将其添加到字符串池中。现在致电System.out.print(al.get(0));
:
Object
对象的String
引用,调用了他的toString()
方法,并且如前所述将对对象实数类型进行评估,不是refence类型,即你将调用String#toString
方法。