如何缩小Java中方法调用的工作?

时间:2014-06-26 07:25:23

标签: java narrowing

为什么会出现编译时错误? 2在编译时是常量,因此这里应允许缩小,因为2在字节范围内。

public class Test {


 public static void main(String[] args) {

    ForTest test=new ForTest();
    test.sum(1, 2); //compile time error here

}

}
class ForTest
{

public int sum(int a,byte b)
{
    System.out.println("method byte");
    return a+b;
}
}

错误是: ForTest类型中的方法sum(int,byte)不适用于arguements(int,int)。

编辑:我认为答案就在这里:http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.3但我没有得到它:(

6 个答案:

答案 0 :(得分:5)

您必须区分分配转换方法调用转换

缩小原始转化

首先,请看JLS §5.1.3

  

原始类型的22个特定转换称为缩小基元转换

     
      
  • [...]

  •   
  • int to byte,short或char

  •   
     

[...]

请注意,这只能解释机制,而不能解释允许或不允许此类转换的位置。

作业转换

接下来,请查看JLS §5.2

  

[...]

     

此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):

     
      
  • 如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。
  •   
     

[...]

这清楚地描述了在赋值byte b = 2中允许从类型 int 到类型 byte 的缩小转换。

方法调用转换

但是,在阅读JLS §5.3时,您不会阅读有关缩小转化的任何内容。所以编译器正在做正确的工作。

答案 1 :(得分:3)

这是因为2被解释为int,不能将其隐式转换为字节。

您的选择是将方法签名更改为(int a, int b),还是明确执行转换:test.sum(1, (byte)2)

答案 2 :(得分:1)

您无法隐式输入强制转换intbyte。 调用方法为:

sum(1, (byte)2); 

答案 3 :(得分:1)

修订回答:

java语言规范说,在查找函数调用的候选匹配项时,根据函数名称找到候选项后,以及实际与形式参数的数量,最终到达{{3} }。

“如果m不是泛型方法,则m适用于松散调用,如果,1≤i≤n,ei在松散的调用上下文中与Fi或ei兼容,则与适用性无关。”

显然,当它到达第二个实际参数时,它决定'int'在'松散调用上下文'中与'byte'不兼容。因此,它拒绝在第1阶段找到的唯一匹配候选人。

我无法在JLS中找到“松散调用”的正式定义。

感谢VikasMangal和KisHanarsecHaGajjar指出我原来答案的愚蠢,这些愚蠢在下面重复以获得永恒的耻辱。

我原来回答的评论如下所示。

Java规范部分phase 2能够执行此操作。

此外,在关于常量赋值的5.2节中,它说

“此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):

如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。“

然而,编译器似乎是按照自己的方式进行的。

答案 4 :(得分:0)

由于Narrowing Primitive Conversions(§5.1.3)表示int缩小byteshortchar。因此,您需要将int强制转换为调用方法的byte。像这样:

test.sum(1, (byte)2);

答案 5 :(得分:0)

您可以使用原始整数实现更多功能。因此,每次编写一个可以是“整数”值的值时,Java都会自动想要进行转换,从而将其视为整数。

与此相反的是当您尝试在此尝试的内容时会发生什么。 Java看到一个可以作为整数的值,但是要将它视为一个字节,你需要明确告诉。这有点像说,好吧,我知道我在做什么,我确实意识到将数字转换成一个字节有其局限性,但我还是希望你能这样做。