对Java中原语隐式缩小的想法感到困惑

时间:2015-01-12 05:22:47

标签: java casting byte primitive

以下看似微不足道的问题已经动摇了我对Java中原语如何运作的理解的核心。

我遇到了术语 "implicit narrowing" ,其中允许较小范围类型的变量保存较大范围类型的文字值,如果该值属于该值更小范围。
据我所知,Java只允许在byte,char,short和int之间。

例如,如果该值足够小以适合字节类型的范围,则字节变量CAN取一个int。

byte b1 = 3; // allowed even though 3 is an int literal
byte b2 = 350; // compilation error because a byte cannot go beyond positive 127

所以,这很好用:

byte k = 3;

但我不知道为什么下面这行不起作用!!

Byte k = new Byte(3);

除非我将后者更改为 Byte k = new Byte((byte)3) ,否则我会收到此编译错误

error: no suitable constructor found for Byte(int)
        Byte k = new Byte(3);                                        
                 ^             
constructor Byte.Byte(byte) is not applicable                    
(actual argument int cannot be converted to byte by method invocation conversion)

error message 的最后一部分似乎有一个线索,其中说:

"... actual argument int cannot be converted to 
 byte by method invocation conversion"

然后关于线索的问题变成:
为什么?!我的意思是,将一个小的int文字分配给一个字节并将一个小的int文字传递给一个类型为byte的方法参数捕获的方法有什么区别?

我知道如果我传递一个int变量就必须使用强制转换。但是,我没有传递变量。相反,我正在传递一个小文字,编译器应该意识到它对于一个字节足够小!!

4 个答案:

答案 0 :(得分:10)

对于文字的赋值和方法调用(包括构造函数),规则是不同的。

根据Java Language Specification (JLS) 8§3.10,Java只有6种文字类型:IntegerLiteral,FloatingPointLiteral,BooleanLiteral,CharacterLiteral,StringLiteral和NullLiteral。

3.10.1进一步说明:

  

如果整数文字后缀为ASCII字母L或l(ell),则其长度为long;   否则它的类型为int(§4.2.1)。

(§4.2.1只是类型范围的规范)

关于IntegerLiteral有近7页,所以我不打算完成整个事情。我只想说int文字在分配过程中被适当地转换为字节和短文。

但是,它在构造函数中的用法完全不同。由于构造函数是一种方法,因此适用其参数的常规规则。

我尝试快速排序JLS中的匹配规则,但它是一个非常漫长而复杂的部分。不用说,在选择要运行的方法时,只会自动进行扩展转换。即,您可以将int传递给期望long而没有明确演员的方法,但除非您明确表达,否则无法将int传递给期望byte的方法施展它。

答案 1 :(得分:3)

我不得不同意它看起来很相似,但对于编译器来说,这是两个非常不同的东西。首先,如你所说,使用隐式缩小来铸造价值。但是,在第二种情况下,您使用的是具有特定签名的构造函数。该签名要求您提供一个字节。可以这样想:如果他们添加了一个构造函数,公共字节(int i)会发生什么?现在突然之间,如果他们允许这样做,你就会改变旧代码的含义。我认为这个特殊情况是为什么不允许这样做,尽管可能还有其他额外的编辑。

答案 2 :(得分:1)

在ASSIGNMENTS期间,整数文字被隐式地向下转换为byte,char,short和int。

因此byte b1 = 3;编译得很好。

请注意,整数文字默认为int类型,因此除非您将整数文字指定给byte类型的变量或将其明确地转换为字节,否则编译器会将文字本身视为int。

这就是你在Byte k = new Byte(3);上得到编译错误的原因。这里你在构造函数中使用一个需要一个字节的int。

答案 3 :(得分:0)

字节k =新字节(3);

1)上述语句将创建一个类型为“Byte”的对象,请记住隐式缩小只能出现在原语中。< / p>

2)在创建字节类型的对象时,构造函数会将参数视为整数,因此我们必须显式投射 byte的参数为:

字节k =新字节((字节)3);

相关问题