在Java中将方法参数传递给类型为byte,int,int的方法参数

时间:2018-07-09 07:30:56

标签: java methods casting byte

以下方法接受三个byte,int,int类型的参数,并且从另一个方法调用该方法,这会导致编译错误,即该方法参数不适用于int,int,int。默认情况下,byte参数不适用直到进行明确的强制转换为止。

 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的默认文字,然后为什么接受字节c = 15而不强制转换而不是方法参数。

先谢谢您。

3 个答案:

答案 0 :(得分:1)

原因是因为当您尝试将int强制转换为byte时,您正在执行缩小原始转换。由于这可能会导致信息丢失,因此编译器要求您进行显式转换(例如,在两种情况下,您都将15显式转换为byte类型时所做的操作)。参见this

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

答案 1 :(得分:1)

您的问题可以归结为:

为什么将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节),然后可以选择扩展原始转换
  •   

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

答案 2 :(得分:0)

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,那么就会有歧义。