跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

在Java里多态是如何实现的_Java多态运行机制说明

Java多态依赖运行时动态绑定,核心是根据对象实际类型调用重写后的方法,需同时满足继承/实现关系、子类重写非static/private/final方法、父类或接口类型引用指向子类实例三个条件。 多态靠动态绑定,不是编译时决定的 Java 多态的核心是「运行时根据对象实际类型调用方法」,而不是看变量声明的类型。比如
Animal a = new Dog()
,编译器只检查
Animal
类里有没有
makeSound()
;真正执行时,JVM 查的是
new Dog()
这个对象的实际类型,然后去
Dog
的方法表里找重写后的实现。 静态方法、
private
方法、
final
方法不参与动态绑定——它们在编译期就绑定了,调用时只看引用的编译时类型 构造方法不能被重写,所以也不构成多态 接口实现和类继承效果一致:只要
Shape s = new Circle()
且
Circle
实现了
draw()
,就触发动态绑定 必须同时满足三个条件,缺一不可 光写个
@Override
不等于有多态;光有继承也不行。真正生效要三者齐备: 存在继承或实现关系(
extends
或
implements
) 子类重写了父类/接口中的非静态、非私有、非 final 方法 使用父类/接口类型引用指向子类实例(即向上转型:
Animal a = new Cat()
) 常见错误:写成
Cat c = new Cat(); c.makeSound();
——这没用到父类引用,只是普通调用,不体现多态;或者子类没加
@Override
却以为重写了,结果调用的还是父类方法。 方法表(vtable)是 JVM 实现动态绑定的关键结构 JVM 为每个类维护一张方法表,表中按签名顺序存放可被动态调用的方法地址。子类加载时,会复制父类方法表,再把重写的方法替换成自己的入口地址。调用时,JVM 直接查这张表,跳转到对应实现。 立即学习 “ Java免费学习笔记(深入) ”; Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 这意味着: 多态调用性能几乎无损耗(现代 JVM 还做了内联优化) 如果子类没重写某个方法,方法表里仍指向父类实现,所以能正常回退
static
方法不在方法表里——它属于类,不依赖实例,所以
Animal.staticMethod()
和
Dog.staticMethod()
是两个独立符号,不构成多态 别混淆重载(Overload)和重写(Override) 重载是编译时多态,发生在同一个类里,靠参数列表区分;重写才是运行时多态,发生在父子类之间,靠实际对象类型区分。两者机制完全不同,混用会导致预期外的行为。 典型陷阱: 父类有
void show(Object o)
,子类加了个
void show(String s)
——这是重载,不是重写,多态不会生效 子类方法返回类型写成
String
,父类是
Object
,没问题(协变返回值);但如果写成
Integer
而父类是
String
,编译直接报错 子类把方法改成
protected
,而父类是
public
,编译通过但运行时报
IllegalAccessError
(访问权限收缩违反重写规则) 真正理解多态,关键不是记住“父类引用子类对象”这句话,而是盯住「运行时对象类型」和「方法是否可被动态绑定」这两个点。其他都是围绕它展开的约束和优化。

相关文章