Java 原语拓宽面试

标签 java

<分区>

你能解释一下为什么结果是“int”吗?如果变量是一个字节,我希望它是“长”的。

public class Test{
      public static void printValue(int i, int j, int k){
            System.out.println("int");
      }

      public static void printValue(byte...b){
            System.out.println("long");
      }

      public static void main(String... args){
            byte b = 9;
            printValue(b,b,b);
      }
}

最佳答案

Java 编译器必须在两种匹配方法之间进行选择。它总是会选择一种不使用可变元数 (varargs) 的方法,而不是使用它的方法。它宁愿将所有 3 个参数提升为 int 以匹配第一个 printValue 而不是使用可变参数。

Section 15.12.2 of the JLS状态:

The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. The phases are:

  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.

  1. 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.

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

(大胆强调我的)

在第一阶段找到匹配的方法(第一个重载),因此编译器甚至不考虑第三阶段——允许可变元数方法——所以 int 被打印。

选择第二个重载(违反直觉打印 long)的一种方法是显式创建一个数组,以便第一个重载无法匹配。

printValue(new byte[]{b,b,b});

关于Java 原语拓宽面试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34752222/

相关文章:

java - 使用线程分割一个大文件

java - 什么版本的 javac 构建了我的 jar?

java - Ninja 框架使用 Maven 安装错误

java - Kubernetes 找不到 jar 文件

java - 不同格式的日期对象不相等

java - 如何防止 Java Web 应用程序中的空字节注入(inject)

java - Android 空对象引用

Java 正则表达式 : X. Y.Z.A

java - 使用数组字符串元素动态调用方法?

java - 将 keystore 密码从无密码更改为非空密码