ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-05-31 00:59:42  阅读:230  来源: 互联网

标签:java variadic-functions jls


有人能帮我理解section 15.12.2.5 of the JLS re: most specific method吗?

(随后是来自JLS的大胆剪切和粘贴)

In addition, one variable arity member method named m is more specific than another variable arity member method of the same name if either:

  • One member method has n parameters and the other has k parameters, where n >= k. The types of the parameters of the first member method are T1, . . . , Tn-1 , Tn[], the types of the parameters of the other method are U1, . . . , Uk-1, Uk[]. If the second method is generic then let R1 … Rp p1, be its formal type parameters, let Bl be the declared bound of Rl, 1lp, let A1 … Ap be the actual type arguments inferred (§15.12.2.7) for this invocation under the initial constraints Ti << Ui,1ik-1, Ti << Uk, kin and let Si = Ui[R1 = A1, …, Rp = Ap] 1ik; otherwise let Si = Ui, 1ik. Then:
    for all j from 1 to k-1, Tj <: Sj, and,
    for all j from k to n, Tj <: Sk, and,
    If the second method is a generic method as described above then Al <: Bl[R1 = A1, …, Rp = Ap], 1lp.
  • One member method has k parameters and the other has n parameters, where n >= k. The types of the parameters of the first method are U1, . . . , Uk-1, Uk[], the types of the parameters of the other method are T1, . . ., Tn-1, Tn[]. If the second method is generic then let R1 … Rp p1, be its formal type parameters, let Bl be the declared bound of Rl, 1lp, let A1 … Ap be the actual type arguments inferred (§15.12.2.7) for this invocation under the initial constraints Ui << Ti, 1ik-1, Uk << Ti, kin and let Si = Ti[R1 = A1, …, Rp = Ap] 1in; otherwise let Si = Ti, 1in. Then:
    for all j from 1 to k-1 , Uj <: Sj, and,
    for all j from k to n , Uk <: Sj, and,
    If the second method is a generic method as described above then Al <: Bl[R1 = A1, …, Rp = Ap], 1lp.

忽略问题泛型,这是否意味着varargs比子类型更重要,或者在确定一种方法是否比另一种更具体时,子类型比varargs更重要?我无法弄清楚.

具体示例:根据JLS,以下哪个compute()方法“更具体”?

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

我很困惑如何解释结果.当第一个参数是String时,编译器选择具有更具体子类型的方法.当第一个参数是Object时,编译器选择具有较少可选varargs的方法.

注意:如果您没有阅读JLS的这一部分,并且您给出的答案取决于参数的类型,那么您并没有帮助我.如果你仔细阅读JLS,除了与泛型相关的部分,“更具体”的定义取决于声明的参数,而不是实际的参数 – 这在JLS的其他部分发挥作用(找不到)它此刻).

例如对于固定的arity方法,compute(String s)将比compute(Object o)更具体.但我试图理解JLS的相关部分:变量arity方法.

解决方法:

> int compute(String s1,Object … others)在调用compute(“hi”,y,y)时更具体,因为String是Object的子类.
> int compute(Object o1,Object o2,Object … others)是compute(y,y,y)的唯一匹配,因为第二个方法接收String作为第一个参数,而JLS15Test不是String的子类

编辑

我的答案取决于具体方法的基础知识,但您的代码只能编译,因为编译器能够以上述方式区分方法.

以下示例甚至不会编译,因为它的含糊不清:

情况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));
}

案例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.

标签:java,variadic-functions,jls
来源: https://codeday.me/bug/20190531/1187409.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有