Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
动态(运行时)多态性在java中是如何工作的?换句话说,JVM如何知道调用哪些方法?_Java_Casting_Jvm_Polymorphism_Upcasting - Fatal编程技术网

动态(运行时)多态性在java中是如何工作的?换句话说,JVM如何知道调用哪些方法?

动态(运行时)多态性在java中是如何工作的?换句话说,JVM如何知道调用哪些方法?,java,casting,jvm,polymorphism,upcasting,Java,Casting,Jvm,Polymorphism,Upcasting,假设您有一个对象的arrayListarrayList arr=new arrayList()然后用几个不同的对象填充此arraylist,所有这些对象都继承自对象 arr.add(new Integer(1)); arr.add("Im a String"); arr.add(new SomeOtherObject); 假设您在arrayList中循环调用.toString()方法,这实际上会按预期工作,调用字符串和整数类的重写toString()方法,让我困惑的是JVM,arrayList

假设您有一个对象的arrayList
arrayList arr=new arrayList()
然后用几个不同的对象填充此arraylist,所有这些对象都继承自
对象

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

假设您在arrayList中循环调用
.toString()
方法,这实际上会按预期工作,调用
字符串
整数
类的重写
toString()
方法,让我困惑的是JVM,arrayList中的
Integer
String
对象被隐式地强制转换为对象,那么JVM究竟是如何知道在将它们放入arrayList之前将它们重新强制转换为任何对象的呢?很抱歉,如果这个问题有一个明显的答案,但这对我来说似乎没有多大意义

每个对象的标题中都存储了它的类型。当您强制转换对对象的引用时,这不会以任何方式改变对象


例如,当您调用
.toString
时,它会从类的描述中查找要调用的方法。注意:如果可以优化代码,它不必每次都这样做。

每个对象的标题中都存储了它的类型。当您强制转换对对象的引用时,这不会以任何方式改变对象


例如,当您调用
.toString
时,它会从类的描述中查找要调用的方法。注意:如果它可以优化代码,则不必每次都这样做。

假设您有一个
Foo
,您有一个名为
arr
ArrayList
。当您说
arr.add(new Foo())
时,
Foo
类的新对象将作为新元素添加到
arr
。这是可能的,因为
Foo
是一个
,从
对象
继承而来。但是,对象是
Foo
,即使
Foo
是从
对象继承的。因此,当您调用它的
toString
时,它将调用您创建的
Foo
对象的
toString


假设您有一个由
Bird
s和
Eagle
s
fly
组成的数组列表。因此,如果你调用
Bird
fly()
方法,它实际上是一只
Eagle
,它会飞得很漂亮。这实际上是继承的一个很好的特性,非常有意义。

假设您有一个
Foo
,您有一个名为
arr
ArrayList
。当您说
arr.add(new Foo())
时,
Foo
类的新对象将作为新元素添加到
arr
。这是可能的,因为
Foo
是一个
,从
对象
继承而来。但是,对象是
Foo
,即使
Foo
是从
对象继承的。因此,当您调用它的
toString
时,它将调用您创建的
Foo
对象的
toString


假设您有一个由
Bird
s和
Eagle
s
fly
组成的数组列表。因此,如果你调用
Bird
fly()
方法,它实际上是一只
Eagle
,它会飞得很漂亮。事实上,这是继承的一个重要特性,非常有意义。

事实是,JVM不知道如何将它们转换回原来的状态。我们必须为此完成任务。考虑这个…(在代码行之后)

您肯定会得到编译时错误。好,现在尝试显式强制转换返回的对象

SomeOtherObject obj = (SomeOtherObject)arr.get(2);
它工作得非常好!为什么?因为从get()方法返回的对象与要强制转换的类型兼容

现在考虑这个(我知道我做不到),只是为了检查JVM能告诉我们哪个对象是什么。< /P>
SomeOtherObject obj = (SomeOtherObject)arr.get(1); //1 instead of 2
是的,我知道这个数组的第二个成员是字符串,我不能这样做。但是让我们看看JVM有什么要说的(尽管没有编译器错误)。我们得到的消息是,无法将对象强制转换为指定的类型。(但我们没有得到对象的确切类型)

你明白了吗?这里的JVM只知道传递给该数组的对象只是与该对象兼容的对象。它不知道我们是否真的传递了字符串、int(或者更确切地说是整数,因为原语不能存储在集合中)或其他对象(Java中定义的任何类都是Object的直接子类)

现在回答你的问题:

  • (我如何才能使字符串和整数恢复正常(尽管我仍然需要对它们进行类型转换))原因是字符串和包装类(Integer是一个包装类)已经重写了从对象继承的toString()方法。因此,打印这些对象会给出实际值

  • (JVM如何知道将它们转换为哪种类型)JVM在返回给用户之前实际上不知道将哪个对象转换为哪种类型。它将只返回对象的一个实例(这是JVM对该对象的全部了解)。我们必须显式地将其转换为适当的类型

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


    关于运行时多态性的详细描述(你的标题问题)在这个网站上给出:

    事实是,JVM不知道如何将它们转换回原来的状态。我们必须为此完成任务。考虑这个…(在代码行之后)

    您肯定会得到编译时错误。好,现在尝试显式强制转换返回的对象

    SomeOtherObject obj = (SomeOtherObject)arr.get(2);
    
    它工作得非常好!为什么?因为从get()方法返回的对象与要强制转换的类型兼容

    现在考虑这个(我知道我做不到),只是为了检查JVM能否告诉我们哪个对象是WHA。