java - 在 Java 中重载重写的方法
问题描述
我有一个实现接口 A 的类 B ,这样:
public interface A {
Map<String, Object> doStuff(Integer param1, Integer Param2);
}
public class B implements A {
public Map<String, Object> doStuff(Integer param1, Integer param2) {
return doStuff(param1, param2, newParam3);
}
public Map<String, Object> doStuff(Integer param1, Integer Param2, boolean param3) {
if (param3)
doSomething;
return doneStuff;
}
}
但是当我尝试访问重载但未覆盖的方法时,我会遇到编译时错误。这不应该很好吗?
解决方案
java 方法调用中有两个完全独立的步骤。
第 1 步是:将方法调用(在您的源代码中)转换为完全限定的方法 ID。这完全发生在编译时。
第 2 步是:现在我们有了一个完全限定的方法 ID,通过动态查找找到该 ID的实际实现x.getClass()
,从对象的实际实例类型 ( ) 开始,然后在层次结构中向上直到找到实现。这完全发生在运行时。
完全限定的方法 ID 包括包、类、方法名称、参数类型和返回类型。
因此,在您的 B 类中,您有2 个不同的方法 ID。并且不同的方法ID是不同的方法;名称相同的事实无关紧要。
换句话说,这:
A x = new B();
x.doStuff(param1, param2);
存储为方法的 INVOKEVIRTUAL/INVOKEINTERFACE com.foo.pkg.A::doStuff(Ljava/lang/Integer;L/java/lang/Integer;)Ljava/util/Map;
。这实际上是在类文件中;看看输出javap
或者用十六进制编辑器打开那个东西,你会在那里找到那个字符串,至少,从doStuff
.
然后仅在运行时,'INVOKEINTERFACE com.foo.pkg.A doStuff(Ljava/lang/Integer;L/java/lang/Integer;)Ljava/util/Map bytecode instruction ends up checking the type of the object that your
x variable is pointing to, figures out it's an instance of
com.foo.pkg.B`,然后实际上调用 B 的这个方法的实现来完成这项工作。
您的第二个 doStuff 方法具有方法 ID B doStuff(Ljava/lang/Integer;Ljava/lang/Integer;Z)Ljava/util/Map;
- 请注意这只是一种完全不同的方法(这个方法中有一个 Z)。
因此,这:
A x = new B();
x.doStuff(1, 2, true);
是编译错误:A 接口根本没有那个方法。
推荐阅读
- python-3.x - 使用 SIFT 从 python 中的多个图像中提取特征
- php - SQLSTATE[HY093]: 参数号无效:参数未定义#
- java - 如何在 QueryBuilders.matchQuery() 中添加过滤器以根据过滤器获取一些匹配的文档
- python - tf-idf vectorizer的use_idf参数说明
- angular - 安装 ng2-opd-popup 时出错
- angularjs - 如何从管理面板提示其他登录用户屏幕上的确认对话框
- sql - BigQuery - 将科学记数法转换为十进制格式
- python - 测试使用 MongoDB 的 Python API
- php - 通过zend rest下载的文件已损坏
- c# - 如何从 C# 中的 word 中提取 .emz 文件