方法调用
方法调用
确定被调用方法的版本
包括
解析调用
和方法分派
解析调用
对于在那些"编译器可知,运行期不可变"的方法,主要包括静态方法和私有方法。前者与类型直接关联,后者外部不可访问,决定了它们都不能通过继承或者别的方式重写出其它版本,适合在类加载阶段进行解析。
对应的字节码指令:invokestatic,invokespecial
解析调用
是静态的过程,在编译器完全确定,在类加载阶段就会把涉及的符号引用全部转化为直接引用,不必延后到运行期再确定。方法调用还有另一种形式:分派
,包括静态分派
和动态分派
。
分派
分派体现了
多态
的特性
静态分派的主要体现就是
方法重载
-
方法重载是根据
静态类型
确定方法版本的,具体来说,子类对象可以指向父类引用,那么等号左边的父类就是静态类型
,在编译器已知,而等号右边的子类是实际类型
,在运行期才能确定下来。 -
静态分派发生在
编译阶段
。编译器虽然能确定方法的重载版本,但很多情况下并不是唯一的,在存在多个合适版本的情况下,会选择最合适
的版本。重载方法的参数类型可以转化的顺序:自动类型转换——>包装类——>接口——>父类——>变长参数
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class Test { static class Human{ } static class Man extends Human{ } static class Woman extends Human{ } public void sayHello(Human human){ System.out.println( "hello,gay." ); } public void sayHello(Man man){ System.out.println( "hello,man." ); } public void sayHello(Woman woman){ System.out.println( "hello,woman." ); } public static void main(String[] args) { Test tx= new Test(); Human man= new Man(); Human woman= new Woman(); tx.sayHello(man); tx.sayHello(woman); } /* hello,gay. hello,gay. */ |
动态分派
动态分派的主要体现是
方法重写
这种多态性的根源在于虚方法调用指令
invokevirtual
的执行逻辑,invokevirtual
第一步就是确定操作数栈顶第一个元素所指向对象的实际类型,也就是在运行期确定方法接收者的实际类型。
-
方法重写是根据
方法接受者的实际类型
来选择方法版本的 -
字段没有多态性,哪个类的方法访问某个名字的字段时,改名字指的就是这个类能看到的那个字段。
1234567891011121314151617181920212223242526public
class
Polymorphism {
static
class
Human{
public
void
show(){
System.out.println(
"hello,guy"
);
}
}
static
class
Man
extends
Human{
public
void
show(){
System.out.println(
"hello,man"
);
}
}
static
class
Woman
extends
Human{
public
void
show(){
System.out.println(
"hello,woman"
);
}
}
public
static
void
main(String[] args) {
Human man=
new
Man();
man.show();
//hello,man
Human woman=
new
Woman();
woman.show();
// hello,woman
man=
new
Woman();
man.show();
// hello,woman
}
}
分类:
JVM
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 提示词工程师自白:我如何用一个技巧解放自己的生产力
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 如何不购买域名在云服务器上搭建HTTPS服务