Java重载规则

2023-12-01

我最近遇到了两个重载问题,我找不到答案,并且没有 java 环境来运行一些测试代码。我希望有人可以帮助我整理 java 编译器在重载时遵循的所有规则的列表,或者交替地向我指出一个已经存在的列表。

首先,当两个方法仅因最终 varargs 参数不同时,在什么情况下会调用每个方法?您可以在没有任何参数的情况下调用 varargs 方法吗?

private void f(int a) { /* ... */ }
private void f(int a, int... b) { /* ... */ }

f(12); // calls the former? I would expect it to
f(12, (int[])null); // calls latter, but passes null for b? 
  // Can I force the compiler to call the second method in the same fashion
  // as would happen if the first method didn't exist?

第二个问题,当两个方法因彼此继承的类型不同而被调用时?我希望调用最派生的版本,并允许强制转换调用另一个版本。

interface A {}
class B implements A {}
class C implements A {}

private void f(A a) {}
private void f(B b) {}

f(new C()); // calls the first method
f(new B()); // calls the second method?
f((A)(new B()); // calls the first method using a B object?

这是两个示例,但作为代码阅读器,我更喜欢用于解决此问题的精确有序规则的规范列表,因为我经常没有时间设置构建环境来检查编译器正在做什么。


重载与覆盖

的选择正确的实施正如您所指出的,of 方法是在运行时完成的,现在要调用的方法的签名是在编译时决定的。

编译时重载方法选择

The Java语言规范(JLS) 第 15.12 节方法调用表达式详细解释了编译器选择要调用的正确方法所遵循的过程。

在那里,你会注意到这是一个编译时任务。 JLS 在第 15.12.2 款中表示:

此步骤使用方法名称 and 参数表达式的类型找到既可用又适用的方法 可能有不止一种这样的方法,在这种情况下选择最具体的一种。

通常,如果可变参数方法与其他候选方法竞争,则它们是最后选择的,因为它们被认为不如接收相同参数类型的方法具体。

要验证其编译时性质,您可以执行以下测试。

声明一个这样的类并编译它(即javac ChooseMethod.java).

public class ChooseMethod {
   public void doSomething(Number n){
    System.out.println("Number");
   }
}

声明第二个类,调用第一个类的方法并编译它(即javac MethodChooser.java).

public class MethodChooser {
   public static void main(String[] args) {
    ChooseMethod m = new ChooseMethod();
    m.doSomething(10);
   }
}

如果您运行该程序(即java MethodChooser),输出显示Number.

现在,添加第二个更具体的超载方法到ChooseMethod类,并重新编译它(但不要重新编译其他类)。

public void doSomething(Integer i) {
 System.out.println("Integer");
}

如果再次运行 main,输出仍然是Number.

基本上,因为它是在编译时决定的。如果你重新编译MethodChooser类(带有 main 的类),然后再次运行程序,输出将是Integer.

因此,如果要强制选择重载方法之一,参数的类型必须与编译时的参数类型相对应,而不仅仅是运行时的参数类型。

在运行时覆盖方法选择

同样,方法的签名是在编译时决定的,但实际的实现是在运行时决定的。

声明一个这样的类并编译它。

public class ChooseMethodA {
   public void doSomething(Number n){
    System.out.println("Number A");
   }
}

然后声明第二个扩展类并编译:

public class ChooseMethodB extends ChooseMethodA {  }

在 MethodChooser 类中,您执行以下操作:

public class MethodChooser {
    public static void main(String[] args) {
        ChooseMethodA m = new ChooseMethodB();
        m.doSomething(10);
    }
}

如果你运行它你会得到输出Number A,这是好的,因为该方法尚未被重写ChooseMethodB因此被调用的实现是ChooseMethodA.

现在,添加一个重写的方法MethodChooserB:

public void doSomething(Number n){
    System.out.println("Number B");
}

重新编译这个,然后再次运行 main 方法。

现在,你得到输出Number B

因此,实现是在运行时选择的,而不是重新编译MethodChooser需要上课。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java重载规则 的相关文章

  • Hibernate注解放置问题

    我有一个我认为很简单的问题 我见过两种方式的例子 问题是 为什么我不能将注释放在字段上 让我举一个例子 Entity Table name widget public class Widget private Integer id Id G
  • 在文本文件中写入多行(java)

    下面的代码是运行命令cmd并使用命令行的输出生成一个文本文件 下面的代码在 Eclipse 的输出窗口中显示了正确的信息 但在文本文件中只打印了最后一行 谁能帮我这个 import java io public class TextFile
  • 如何在android上的python kivy中关闭应用程序后使服务继续工作

    我希望我的服务在关闭应用程序后继续工作 但我做不到 我听说我应该使用startForeground 但如何在Python中做到这一点呢 应用程序代码 from kivy app import App from kivy uix floatl
  • Java:如何从转义的 URL 获取文件?

    我收到了一个定位本地文件的 URL 事实上我收到的 URL 不在我的控制范围内 URL 按照 RFC2396 中的定义进行有效转义 如何将其转换为 Java File 对象 有趣的是 URL getFile 方法返回一个字符串 而不是文件
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Java AES 128 加密方式与 openssl 不同

    我们遇到了一种奇怪的情况 即我们在 Java 中使用的加密方法会向 openssl 生成不同的输出 尽管它们在配置上看起来相同 使用相同的键和 IV 文本 敏捷的棕色狐狸跳过了懒狗 加密为 Base64 字符串 openssl A8cMRI
  • JAVA - Xuggler - 组合 MP3 音频文件和 MP4 电影时播放视频

    使用 JAVA 和 Xuggler 以下代码组合 MP3 音频文件和 MP4 电影文件并输出组合的 mp4 文件 我希望在合并音频和视频文件时应自动播放输出视频文件 String inputVideoFilePath in mp4 Stri
  • java中如何连接字符串

    这是我的字符串连接代码 StringSecret java public class StringSecret public static void main String args String s new String abc s co
  • 按第一列排序二维数组,然后按第二列排序

    int arrs 1 100 11 22 1 11 2 12 Arrays sort arrs a b gt a 0 b 0 上面的数组已排序为 1 100 1 11 2 12 11 22 我希望它们按以下方式排序a 0 b 0 首先 如果
  • 如何在不超过最大值的情况下增加变量?

    我正在为学校开发一个简单的视频游戏程序 我创建了一个方法 如果调用该方法 玩家将获得 15 点生命值 我必须将生命值保持在最大值 100 并且由于我目前的编程能力有限 我正在做这样的事情 public void getHealed if h
  • 如何安全地解决这个 Java 上下文类加载器问题?

    我的数百名用户中只有一位在启动我的 Java 桌面应用程序时遇到问题 他只有大约三分之一的时间开始 另外三分之二的时间在启动时抛出 NullPointerException Exception in thread AWT EventQueu
  • 我需要什么库才能在 Java 中访问这个 com.sun.image.codec.jpeg?

    我正在用java创建一个图像水印程序 并导入了以下内容 import com sun image codec jpeg JPEGCodec import com sun image codec jpeg JPEGEncodeParam im
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 如何模拟从抽象类继承的受保护子类方法?

    如何使用 Mockito 或 PowerMock 模拟由子类实现但从抽象超类继承的受保护方法 换句话说 我想在模拟 doSomethingElse 的同时测试 doSomething 方法 抽象超类 public abstract clas
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • Jersey 客户端请求中未设置 Content-Length-Header

    我正在使用 Jersey Client 访问网络服务 如下所示 response r accept MediaType TEXT PLAIN TYPE header content length 0 post String class 其中
  • 在 Spring 中重构这个的最佳方法?

    private final ExecutorService executorParsers Executors newFixedThreadPool 10 public void parse List
  • Java中的Object类是什么?

    什么是或什么类型private Object obj Object http download oracle com javase 6 docs api java lang Object html是Java继承层次结构中每个类的最终祖先 从
  • Eclipse 中 Spring MVC 模型对象的 (jsp /jstl) 视图中的代码辅助

    在 Spring MVC 中 当将对象放置在视图模型中时 如下所示 public String getUser Model model fetch user model addAttribute user user return viewN
  • 在 RESTful Web 服务中实现注销

    我正在开发一个需要注销服务的移动应用程序 登录服务是通过数据库验证来完成的 现在我陷入了注销状态 退一步 您没有提供有关如何在应用程序中执行身份验证的详细信息 并且很难猜测您在做什么 但是 需要注意的是 在 REST 应用程序中 不能有会话

随机推荐

  • 当组件在 jasper 报告中动态不可见时,如何避免组件之间出现空格? [复制]

    这个问题在这里已经有答案了 我这里有大约 11 个 staticText 组件 当我只显示第一个和第八个组件时 我发现它们之间存在巨大差距 每个组件之间没有任何空间 我的假设是组件上的 isRemoveLineWhenBlank true
  • Django Rest Framework 递归嵌套父序列化

    我有一个模型 其中有一个名为 parent 的自引用字段 模型 class Zone BaseModel name models CharField max length 200 parent models ForeignKey self
  • 删除除...(*.BAT)之外的所有文件夹

    我想删除父目录中除 MYFOLDER 之外的所有文件夹 但我无法完成此操作 for i in C Parent do if not i MYFOLDER del f q i 有人可以检查一下代码吗 我使用的是 bat 这应该可以帮助您 fo
  • 如何在使用 HttpClient 获取时阻止 DNS 查找

    我不确定我做得是否正确 下面的方法可以防止DNS lookup when keep alive设置为假 主持人是 tatoeba org 网址是 http 188 213 24 161 eng sentences show 1 这里截图 u
  • 在node.js中的同一端口上绑定HTTP和HTTPS流量?

    我有一个场景 我的 node js 应用程序位于负载平衡 HAProxy 后面 该代理将 HTTP 和 HTTPS 流量转发到我的节点服务器上的端口 8000 不幸的是 这让我陷入了一个棘手的境地 我需要为我的 http 和 https 服
  • 固定宽度字段的正则表达式

    我需要将文件布局上的固定宽度字段与正则表达式进行匹配 该字段是数字 整数 始终有四个字符 并且包含在 0 1331 范围内 当数字小于 1000 时 字符串将用左零填充 所以所有这些例子都是有效的 0000 0001 0010 1000 1
  • 为什么是“使用命名空间 X;”不允许在类/结构级别?

    class C using namespace std error namespace N using namespace std ok int main using namespace std ok 我想知道其背后的动机 我不太清楚 但我
  • 小部件问题:BroadcastQueue:不允许后台执行:接收 Intent

    我的应用程序小部件在升级到 targetSDk 到 28 后停止工作 它可以在旧的 Targetsdk 设备上完美运行 我收到以下错误 W BroadcastQueue Background execution not allowed re
  • 重复结果

    我正在 SQL Server2005 中编写一个查询 这在结果中返回了重复的行 我可以用特定列作为键来消除这种重复吗 您可以使用 DISTINCT 关键字消除完全重复的行 如果有一些键列是重复的 但其余列不是 那么您将必须使用聚合函数和 G
  • playJoin 未定义、输入意外结束以及文件未正确导入

    我有一个非常简单的 JavaScript 函数 可以循环播放音频文件夹中的一些歌曲 然而 下面的代码会产生 Uncaught ReferenceError playJoin is not defined 即使它应该被定义为一个函数 我通过验
  • 我想为可滚动面板设置限制滚动

    我制作了一个可滚动面板 如下所示 private void button3 Click object sender EventArgs e Form f2 new Form f2 Size new Size 400 300 f2 AutoS
  • 具有动态生成的输入字段的 Angular 指令无法显示验证

    经过 3 天的搜索 stackoverflow 和其他网站后 我发现自己又回到了原点 我的任务 我需要验证动态生成的表单字段 HTML
  • 使浮动的 QDockWidget 无法获得焦点

    我正在 QDockWidget 中创建一个简单的虚拟键盘 当小部件停靠到 QMainWindow 中时 所选小部件 例如 qdoublespinbox 会突出显示 如果我单击虚拟键盘 clearFocus 就会起作用 当 QDockWidg
  • 传递给 Array.prototype.every 的函数中的“可变变量可从闭包访问”

    代码会比我说的更清楚 var candidateIndex 0 var minValue Number MAX VALUE topArray every function element index if element innerArra
  • 如何在 NSOperation 中启动异步 NSURLConnection?

    我想在后台线程上的 NSOperation 内部执行异步 NSURLConnection 这是因为当数据返回时我正在对数据进行一些非常昂贵的操作 这与他们在这里提出的问题非常相似 如何在 NSOperation 中执行异步 NSURLCon
  • 无法将 git 与 aptana 一起使用

    当我尝试将某些内容放在 git 服务器上时 它给了我一个错误 引用未定义的变量 USER 在 bash 中 echo USER 给了我正确的答案 会是什么呢 这是带有 aptana 3 插件的 eclipse 一整包 bash 会话可能设置
  • 如何在android本机代码中使用共享内存?

    我正在将现有的 Linux 应用程序移植到 Android 该应用程序正在使用共享内存 API 例如shm open etc 检查android 源码中的仿生 我发现这些 API 不受支持 因此 我在构建过程中遇到链接错误 external
  • 类的全局实例

    仍在尝试了解 C 主要使用 C 我有一个 Device 类 并且想要创建该类的实例 但也希望全局访问这些实例 因为我在 GUI 方法中经常使用它们 public class Device public string Name public
  • 在 for 循环中使用 PdfStamper 的最佳方法

    我有以下iText代码读取文件并将其添加到主 PDF 文件中 因此它基本上是在现有 PDF 的绝对位置添加 PDF 页面 主 PDF 中的绝对位置和页码将动态确定 有时它可能位于第 1 页100 100 x y 或第 2 页250 250
  • Java重载规则

    我最近遇到了两个重载问题 我找不到答案 并且没有 java 环境来运行一些测试代码 我希望有人可以帮助我整理 java 编译器在重载时遵循的所有规则的列表 或者交替地向我指出一个已经存在的列表 首先 当两个方法仅因最终 varargs 参数