在Java中如何指定字节字面量?

278
如果我有一个方法
void f(byte b);

如何在不进行强制转换的情况下使用数字参数调用它?

f(0);

出现错误。


1
@oliholz 这是降级转换,需要额外的解析开销。 - Ben Barkay
6个回答

327

无法直接传递基本数值类型作为字节参数。因为基本数值常量被视为整数(如果后面跟着一个"L"则被视为长整数),所以您必须显式地将其强制转换为byte类型。就我所知,没有捷径可以实现这一点。


17
如果你需要经常进行这种操作,可以定义一个简单的帮助方法 byte b(int i) {return (byte) i; } 并将其静态导入。然后你就可以写成 f(b(10))。 - Yona Appletree

144

恐怕你需要进行类型转换:

f((byte)0);

我相信这会在编译时执行适当的转换,而不是在执行时执行,所以它实际上不会导致性能损失。只是有点不方便:(


16
+1 表示对编译时转换的支持。如果你了解编译器并且相信语言设计者(我们应该这样做),那么这是很常识的,但否则可能并不那么明显。 - Philip Guin

36
你可以在Java中使用字节字面量...有点类似。
    byte f = 0;
    f = 0xa;

0xa(int字面量)会自动转换为byte。它不是真正的byte字面量(请参见JLS和下面的注释),但是如果它像鸭子一样嘎嘎叫,我就称它为鸭子。

你不能这样做:

void foo(byte a) {
   ...
}

 foo( 0xa ); // will not compile

你必须进行如下类型转换:

 foo( (byte) 0xa ); 

请记住,这些都将被编译,并且它们使用的是“字节文字”:

void foo(byte a) {
   ...
}

    byte f = 0;

    foo( f = 0xa ); //compiles

    foo( f = 'a' ); //compiles

    foo( f = 1 );  //compiles

当然,这也可以编译。
    foo( (byte) 1 );  //compiles

23
这些并不是字节字面量。它们是其他类型(主要是int)的字面量,正在被隐式转换为字节。例如,1 是一个int字面量,但是 double d = 1; 可以编译通过。 - smehmood
如果您已经在使用技巧了,在静态导入 byte b(int i){} 的情况下,b(1) 作为 long 类型会比 f=1 更加简单。 - Elazar Leibovich
1
@smehmood,但由于转换是由预编译器/编译器(在程序开始运行之前)完成的,而不是运行时完成的,那么它就是一个字面值,不是吗? - Pacerier
3
@Pacerier 这是一个字面量,不是“字节字面量”,而是整型。编译器会将它视为整型字面量(应该如此),并在赋值时执行隐式的下转换(也应该如此)。它在任何时候都不被解析为“字节字面量”(这种不存在)。请参见JLS第5.2节,特别是关于缩小转换的后半部分。唯一涉及的是整数常量和将适当的赋值转换规则应用于字节变量。 - Jason C
我给这个答案点赞是因为这种技术很新颖,但实际上,在Java中并没有“字节文字”。 - user719662

13

如果你在代码中传递字面量,那么有什么阻止你事先声明它呢?

byte b = 0; //Set to desired value.
f(b);

3
这还可以让你给这个值取一个更有意义的名称。http://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants - Aaron J Lang
这很有用。如果你想使用Java的“fill”方法填充一个字节数组,这是最明智的选择。 - user1086498
编译器刚刚抱怨了以下内容,因此我需要添加强制转换:public static final byte BYTE_MASK = (byte)0xff; - Marvo
我意识到我实际上想要 byte BYTE_MASK = 0x000000ff;,以免出现一些令人讨厌的符号扩展错误。 - Marvo

5

如果要覆盖方法,该怎么做?

void f(int value)
{
  f((byte)value);
}

这将允许执行 f(0)

31
这对代码的可读性非常不好。当人们尝试传入比byte类型能够容纳的值更大的值时,可能会导致问题。我不建议使用这种方法! - Rolf ツ
4
同时,这个转换将在运行时发生。非常糟糕。 - BrainSlugs83
完全同意Rolf (Tsu)的观点,可能值得补充的是,从技术上讲,这是重载而不是覆盖。 - Cromax
这不是你应该使用重写的方式,这会给用户带来很多错误。强制转换是确保类型安全的一种方法。 - Agnibha

-3

26
二进制字面量 != 字节字面量。 - Marcello Nuccio
1
你仍然在进行字节下转换。 - M.kazem Akhgary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接