Java:编译时解析和“最具体的方法”,因为它适用于变量数量

2023-12-02

有人可以帮助我理解吗JLS re:最具体方法的第 15.12.2.5 节?

(以下是来自 JLS 的猛击剪切和粘贴)

此外,如果满足以下任一条件,则一个名为 m 的变量 arity 成员方法比另一个同名的变量 arity 成员方法更具体:

  • 一个成员方法有 n 个参数,另一个有 k 个参数,其中 n >= k。第一个成员方法的参数类型为T1,...。 。 。 , Tn-1 , Tn[],另一个方法的参数类型为U1, . 。 。 ,Uk-1,Uk[]。如果第二种方法是泛型的,则令 R1 ... Rp p1 为其形式类型参数,令 Bl 为 Rl、1lp 的声明边界,令 A1 ... Ap 为推断的实际类型参数(第 15.12.2.7 节)对于此调用,在初始约束 Ti
  • 一个成员方法有 k 个参数,另一个有 n 个参数,其中 n >= k。第一个方法的参数类型为U1,. 。 。 ,Uk-1,Uk[],另一个方法的参数类型为T1,. 。 ., Tn-1, Tn[]。如果第二种方法是泛型的,则令 R1 ... Rp p1 为其形式类型参数,令 Bl 为 Rl、1lp 的声明边界,令 A1 ... Ap 为推断的实际类型参数(第 15.12.2.7 节)对于此调用,在初始约束下 Ui

忽略泛型问题,这是否意味着在确定一种方法是否比另一种方法更具体时,可变参数比子类型更重要,或者子类型比可变参数更重要?我想不通。

具体例子:下列哪一项compute()根据 JLS,方法“更具体”?

package com.example.test.reflect;

class JLS15Test
{
    int compute(Object o1, Object o2, Object... others) { return 1; }
    int compute(String s1, Object... others)            { return 2; }

    public static void main(String[] args) 
    {
        JLS15Test y = new JLS15Test();
        System.out.println(y.compute(y,y,y));
        System.out.println(y.compute("hi",y,y));
    }
}

我不知道哪个是“更具体”;输出打印

1
2

我很困惑如何解释结果。当第一个参数是字符串时,编译器会选择具有更具体子类型的方法。当第一个参数是对象时,编译器会选择可选可变参数数量较少的方法。


NOTE:如果您没有阅读 JLS 的这一部分,并且您给出的答案取决于论点,你没有帮我。如果你仔细阅读JLS,除了与泛型相关的部分之外,“更具体”的定义取决于声明的参数,而不是实际的参数-- 这在 JLS 的其他部分发挥作用(目前找不到)。

例如对于固定数量方法,compute(String s)会比更具体compute(Object o)。但我试图了解 JLS re: 变量数量方法的相关部分。


  1. int compute(String s1, Object... others)当你打电话时会更具体compute("hi",y,y), since String是对象的子类。

  2. int compute(Object o1, Object o2, Object... others) is the only匹配compute(y,y,y)因为第二个方法接收 String 作为第一个参数,并且JLS15Test不是 的子类String

EDIT

我的答案基于特定方法的基础知识,但您的代码只能编译,因为编译器能够以上述方式区分方法。

由于含糊不清,以下示例甚至无法编译:

case 1:

int compute(Object o1, Object o2, Object... others) { return 1; }
int compute(Object s1, Object... others)            { return 2; }

public static void main(String[] args) 
{
    JLS15Test y = new JLS15Test();
    System.out.println(y.compute(y,y,y));
    System.out.println(y.compute("hi",y,y));
}

case 2:

int compute(String o1, Object o2, Object... others) { return 1; }
int compute(Object s1, String... others)            { return 2; }

public static void main(String[] args) 
{
    JLS15Test y = new JLS15Test();
    System.out.println(y.compute("hi","hi","hi"));
}

更多 编辑

前两次我没有很好地回答你的问题(我希望这次我能回答:))。

您正在谈论的实际案例将如下所示:

public class Test {
    public static void main(String[] args)
    {
        Test t = new Test();
        int a = t.compute("t", new Test());
        System.out.println(a);
    }

    int compute(String s, Object... others) { return 1; }
    int compute(Object s1, Object others)   { return 2; }
}

在这种情况下,compute(Object s1, Object others)那么确实更具体compute(String s, Object... others)(参数较少)所以输出将是2 indeed.

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

Java:编译时解析和“最具体的方法”,因为它适用于变量数量 的相关文章

随机推荐

  • 替换所有出现的“.”使用 sed 在 '=' 之前加上 '_'

    我有一个属性文件如下 build number 153013 db create tablespace 0 db create user 0 db create schema 0 upgrade install 1 new install
  • 如何在 type="text/ng-template" 的页面中使用 javascript?

    我有这样的代码
  • 模板的显式实例化

    这个线程确实很有帮助 但我仍然对这个过程有疑问 但似乎没有得到解答 我必须在多大程度上显式实例化模板 例如 如果在我的定义文件中 我在每个函数 友元类 运算符重载等上使用模板 我是否必须在模板实例化文件中实例化每个模板 我正在使用的当前方法
  • 如何读取函数调用后的代码块?

    我是 swift 新手 我需要帮助阅读以下代码 函数调用 self table update completedItem 之后的代码块的含义是什么 代码块第一行的 result error 的含义是什么 self table update
  • Objective-C中如何动态加载类?

    如何在 Objective C 中动态加载类 根据我的需要 类名将位于一个文本文件中 我需要读取它 然后动态加载该类 这段代码正在 Java 中加载一个类 我希望在 Objective C 中完成相同的功能 public class Mai
  • C 中数组的 & 运算符定义

    最近的一个问题引发了一场围绕数组和指针的讨论 这个问题是指scanf s name vs scanf s name 对于下面的代码 微软实际上在VS2010 也许更早的版本 中为你解决了这个问题 include
  • 从数据库中获取中值

    中位数定义为将数据集的上半部分与下半部分分开的数字 从 STATION 查询北纬度 LAT N 的中位数 并将结果四舍五入到小数位 输入格式 STATION表描述如下 Field Type ID NUMBER CITY VARCHAR2 2
  • Quickblox 网页版 - 创建 1 对 1 聊天

    我正在尝试从网络客户端创建一对一聊天 我下载了SDK和群聊示例 除了网络之外 所有平台似乎都有很好的例子 例如 http quickblox com developers Android XMPP Chat Sample 任何人都可以提供代
  • jQuery 验证适用于输入 type="submit",但不适用于 html 按钮元素。为什么?

    使用 ASP NET 为什么 bassistance de jQuery 验证插件在使用 input type submit 元素而不是 html 按钮元素时阻止表单提交 使用 html 按钮 type submit 标记时会触发验证 但表
  • Ansible 正则表达式转义美元字符

    我正在尝试使用 Ansible 修改配置文件中的 URL 值 CONSOLE URI http 172 18 18 103 controller 我正在使用 lineinfile 模块 但它不起作用 我尝试用双反斜杠转义 但它也不起作用 l
  • 在 Google App Engine 上选择 Java 与 Python

    目前 Google App Engine 支持 Python 和 Java Java 支持不太成熟 然而 Java 似乎有更长的库列表 尤其是对 Java 字节码的支持 无论用于编写该代码的语言如何 哪种语言能提供更好的性能和更强大的功能
  • 新旧风格类中的Python析构函数[重复]

    这个问题在这里已经有答案了 我试图理解为什么对象销毁在新样式类中与旧样式类中的工作方式不同 class Wrapper class Inner object def del self print Inner destructor inner
  • Angular cli 2错误无法通过AOT构建解析XXXXX的所有参数

    import Injectable Inject from angular core import Subject from rxjs Subject import CompleterData CompleterItem from ng2
  • 解析Java中类似乳胶的语言

    我正在尝试用 Java 为类似于 Latex 的简单语言编写一个解析器 即它包含大量非结构化文本 中间有几个 commands with some parameters 像 这样的转义序列也必须考虑在内 我尝试用 JavaCC 生成一个解析
  • 从片段中的 sqlite 动态设置复选框

    我无法找出在列表视图中存储和显示复选框的最佳方法 现在我在 getView 方法中有代码 Override public View getView final int position View convertView ViewGroup
  • 在 Node.js 中克隆对象

    在 Node js 中克隆对象的最佳方法是什么 例如我想避免出现以下情况 var obj1 x 5 y 5 var obj2 obj1 obj2 x 6 console log obj1 x logs 6 该对象很可能包含复杂类型作为属性
  • 从文本文件中删除最后一行

    我需要从文本文件中删除最后一行 我知道如何在 C 中打开和保存文本文件 但如何删除文本文件的最后一行 文本文件的大小始终不同 有些有 80 行 有些有 20 行 有人可以告诉我该怎么做吗 Thanks 通过少量的行 你可以轻松地使用这样的东
  • 使用C连续读取已打开的文件

    我正在实现一个低重量的应用程序 我必须经常打开并读取 proc pid 或 tid task stat 详细信息 如果应用程序是多线程的 我必须阅读更多统计文件 因此打开 读取和关闭使我的监控应用程序非常慢 有没有办法避免重复打开文件并且仍
  • 多色单一图标

    我为 Fontawesome 图标定义了一些样式 将浏览器图标着色为相应的品牌颜色 所以 Opera 图标是红色的 IE 图标是蓝色的 Firefox 图标是橙色的 但由于 Chrome 有 4 种不同的颜色 而且分离得非常严格 我想知道是
  • Java:编译时解析和“最具体的方法”,因为它适用于变量数量

    有人可以帮助我理解吗JLS re 最具体方法的第 15 12 2 5 节 以下是来自 JLS 的猛击剪切和粘贴 此外 如果满足以下任一条件 则一个名为 m 的变量 arity 成员方法比另一个同名的变量 arity 成员方法更具体 一个成员