【问题标题】:Passing method arguments to the method parameters of type byte,int,int in javajava中将方法参数传递给byte,int,int类型的方法参数
【发布时间】:2018-12-16 19:41:45
【问题描述】:

以下方法接受byte,int,int 类型的三个参数,并且从另一个方法调用该方法,这会产生编译错误,即方法参数不适用于int,int,int。默认情况下,直到显式转换才能识别字节参数完成了。

 public double subtractNumbers(byte arg1,int arg2,int arg3) {
    double sum=arg1+arg2+arg3;
    return sum;
}

现在方法调用另一个方法如下

 public void call(){
  subtractNumbers(15,16,17);   /*Compile error,but 15 is in byte acceptable 
 range of -128 to 127 */
  }

如果我将上述调用更改为subtractNumbers((byte)15,16,17);,它可以正常工作

当我将变量声明为byte c=15 时,它被接受,但是当将 15 传递给字节参数时,为什么会出现编译错误;

int 是 byte,short,int,long 的默认文字,那么为什么 byte c=15 被接受而不进行强制转换而不是方法参数。

提前谢谢你。

【问题讨论】:

  • 它猜测是因为方法重载:您可以有另一个 subtractNumbers 方法,其第一个参数为 int,在这种情况下,subtractNumber(15,16,17) 将调用第二个。
  • 通过执行(byte) 15byte c = 15 你将这个int 值向下转换为byte,所以没有编译错误

标签: java methods casting byte


【解决方案1】:

原因是当您尝试将int 转换为byte 时,您正在执行缩小基元转换。由于这会导致信息丢失,因此编译器要求您进行显式转换(即,就像您在两种情况下将 15 显式转换为 byte 类型时所做的那样)。见this

要回答您关于为什么可以简单地声明byte c = 15 而没有编译错误的其他问题,这是因为15 仍在byte 允许的-128 到-127 范围内。如果您尝试分配更大的值,例如byte d = 128,您仍然会收到编译时错误。见this

【讨论】:

    【解决方案2】:

    您的问题归结为:

    为什么将15 分配给byte 在变量声明中起作用:

    byte b = 15;
    

    但不是在调用方法时?

    subtractNumbers(15,16,17);
    

    这是因为这两种情况处于两个不同的上下文中。第一个在赋值上下文中,而第二个在调用上下文中。

    根据JLS §5.2 Assignment Contexts

    分配上下文允许使用以下之一:

    ...

    另外,如果表达式是一个常量表达式(§15.28) 输入 byte、short、char 或 int:

    • 如果变量的类型是 byte、short 或 char,并且常量表达式的值是 可以用变量的类型来表示。

    15 肯定是一个常量表达式,因此允许从intbyte 的缩小原语转换。

    然而,在调用上下文中,这是不正确的:

    JLS §5.3 Invocation Context

    严格的调用上下文允许使用以下之一:

    • 身份转换 (§5.1.1)
    • 扩大的基元转换 (§5.1.2)
    • 扩大参考转换 (§5.1.5)

    松散的调用上下文允许更宽松的转换集, 因为它们仅用于特定调用,如果没有 可以使用严格的调用上下文找到适用的声明。 松散的调用上下文允许使用以下之一:

    • 身份转换 (§5.1.1)
    • 扩大的基元转换 (§5.1.2)
    • 扩大参考转换 (§5.1.5)
    • 装箱转换(第 5.1.7 节)可选地后跟扩大参考转换
    • 拆箱转换(第 5.1.8 节)可选地后跟扩展原语转换

    没有提到“缩小原语转换”,所以在调用上下文中是不允许的。

    【讨论】:

      【解决方案3】:

      Java 有这种编译时间缩减的想法。这允许以下内容在编译时有效:

      byte b = 15;
      

      大多数人都被告知像 12 这样的字面值将默认为 int。这并非总是如此。 doublefloatlong 等类型具有显式文字(例如 15d15f15L),但 32 位以下的非浮点原语没有。

      这就是为什么15 在编译时被确定为byte 类型。

      在您的情况下,编译器试图在编译时执行类型匹配。方法subtractNumbers 的方法签名为byteintint,因此您必须给它一个精确匹配。不幸的是,在此过程中,编译器在推断15 的类型之前不会查看可用方法列表。我相信这是由于方法过载造成的。

      考虑一下:

      public static void test(byte a, int b){}
      public static void test(int a, int b){}
      

      现在如果你调用test(15, 16),如果15被允许自动缩小到byte,那么就会有歧义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-16
        • 2014-03-25
        • 2013-10-04
        • 2018-08-26
        • 1970-01-01
        • 2014-06-03
        • 2015-05-30
        相关资源
        最近更新 更多