2017-01-08 15 views
0

假设你有对象ArrayList<Object> arr = new ArrayList<Object>();的ArrayList,然后填写此ArrayList有几个不同的对象,它们都来自object继承。动态(运行时)多态性如何在java中工作?换句话说,JVM如何知道要调用哪些方法?

arr.add(new Integer(1)); 
arr.add("Im a String"); 
arr.add(new SomeOtherObject); 

说你然后遍历数组列表调用.toString()方法,这实际上会如预期,称StringInteger类的重载toString()方法,是什么让我困惑的是,在JVM中,IntegerString arrayList中的对象被隐式地转换为对象,那么JVM知道如何在它们被放入arrayList之前将它们变回原来的状态?很抱歉,如果这个问题有一个显而易见的答案,但是这似乎没有多大意义的,我

+0

铸造是不是除了基本类型的情况中的转换。 – EJP

回答

4

每个对象都有它的类型存储在该对象的标题。当您将引用转换为对象时,这不会以任何方式更改对象。

当你调用.toString例如,它查找从班描述调用该方法。注意:如果可以优化代码,则不必每次都这样做。

1

假设你有一个Fooclass,并且你有一个叫arrArrayList<Object>。当你说arr.add(new Foo())Fooclass一个新的对象添加到arr作为新元素。这是可能的,因为Fooclass并且从Object继承。但是,该对象是Foo,即使FooObject继承。因此,当您拨打toString时,它会调用您创建的Foo对象的toString

让我们假设你有一个数组列表Bird s和Eagle s fly精美。因此,如果您拨打Birdfly()方法(实际上是Eagle),它会飞得很漂亮。这实际上是继承的一个重要特征,它非常有意义。

1

事实是,JVM不知道如何将它们转换回原来的。我们将不得不为此完成任务。考虑这个...

SomeOtherObject obj = arr.get(2); //trying to access the third element 

你一定会得到编译时错误(你的代码行之后)。好吧,现在尝试显式转换返回的对象。

SomeOtherObject obj = (SomeOtherObject)arr.get(2); 

它工作得很好!为什么?因为get()方法返回的对象与它正在播放的类型兼容。

现在考虑这个还(我知道我不能这样做),只是为了检查,如果JVM能告诉我们哪些对象是什么。

SomeOtherObject obj = (SomeOtherObject)arr.get(1); //1 instead of 2 

是的我知道这个数组的第二个成员是一个字符串,我不能这样做。但让我们看看JVM有什么要说的(虽然没有编译器错误)。我们得到的消息是该对象不能转换为指定的类型。 (但我们没有得到对象的确切类型)。

你明白了吗?这里的JVM只知道传递给这个数组的对象只是与Object兼容的对象。它不知道我们是否真的传递了String,int(或者整数,因为原语不能存储在集合中),或SomeOtherObject(Java中定义的任何类是Object的直接子类)。

现在回答你的问题:

  1. (我怎么能得到String和整数恢复正常(虽然我仍然要类型转换它们))的原因是字符串和包装类(Integer是一个包装类)重写了从Object继承的toString()方法。所以打印这些对象会给出实际的价值。 (JVM如何知道将其转换为哪种类型)在返回给用户之前,JVM实际上不知道哪个对象将被转换为哪种类型。它只会返回Object的一个实例(这就是JVM所知道的对象)。我们必须明确地将其转换为适当的类型。

希望我回答了你的问题。如果不清楚,请告诉我。

有关运行时多态性(你的标题问题)详细说明在这个网站给出:http://www.javatpoint.com/runtime-polymorphism-in-java

相关问题