为什么对于char,编译器为什么更喜欢int重载而不是varargs char重载? [英] Why does the compiler prefer an int overload to a varargs char overload for a char?

查看:103
本文介绍了为什么对于char,编译器为什么更喜欢int重载而不是varargs char重载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码

public class TestOverload {

    public TestOverload(int i){System.out.println("Int");}
    public TestOverload(char... c){System.out.println("char");}

    public static void main(String[] args) {
        new TestOverload('a');
        new TestOverload(65);
    }
}

输出

Int
Int

这是预期的行为吗?如果是这样,那为什么呢?我正在期待:char,Int

Is it expected behaviour? If so, then why? I am expecting: char, Int

注意:我正在使用Java 8

Note: I am using Java 8

推荐答案

当编译器确定选择哪种重载方法时,具有varargs(...)的方法具有最低的优先级.因此,当使用单个char参数'a'调用TestOverload时,将选择TestOverload(int i)而不是TestOverload(char... c),因为char可以自动提升为int.

Methods with varargs (...) have the lowest priority when the compiler determines which overloaded method to choose. Therefore TestOverload(int i) is chosen over TestOverload(char... c) when you call TestOverload with a single char parameter 'a', since a char can be automatically promoted to an int.

JLS 15.12.2 :

  1. 第一阶段(第15.12.2.2节)执行重载解析,不允许装箱或拆箱转换,或者使用可变Arity 方法调用.如果在此阶段找不到适用的方法 然后处理继续到第二阶段. 这样可以保证在Java编程中有效的所有调用 因此,Java SE 5.0之前的语言不被认为是含糊的 可变arity方法,隐式拳击和/或 拆箱.但是,声明了可变arity方法(第8.4.1节) 可以更改为给定方法调用选择的方法 表达式,因为可变arity方法被视为固定方法 第一阶段的Arity方法.例如,声明m(Object ...) 在已经声明m(Object)的类中导致m(Object)为no 对于某些调用表达式(例如m(null)),将选择更长的时间,例如 m(Object [])更具体.

  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase. This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.

第二阶段(第15.12.2.3节)在允许装箱和拆箱的同时执行重载解析,但是仍排除使用可变arity方法调用.如果在此期间找不到适用的方法 阶段,然后处理继续到第三阶段.这确保了永远不会通过可变Arity选择方法 如果通过固定Arity方法适用,则进行方法调用 调用.

The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase. This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.

第三阶段(第15.12.2.4节)允许重载与可变arity方法,装箱和拆箱相结合.

The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

您希望强制编译器调用TestOverload(char... c)构造函数,您可以传递给构造函数调用char[]:

It you wish to force the compiler to call the TestOverload(char... c) constructor, you can pass to the constructor call a char[] :

new TestOverload (new char[] {'a'});

这篇关于为什么对于char,编译器为什么更喜欢int重载而不是varargs char重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆