Java的L号(长号)规范


96

看来,当您使用Java输入数字时,编译器会自动将其读取为整数,这就是为什么当您输入(long)6000000000(不在整数范围内)时会抱怨6000000000不是整数。为了纠正这一点,我必须指定6000000000L。我刚刚了解了此规范。

还有其他数字规范,例如short,byte,float,double吗?似乎这些内容会很好,因为(我假设)如果您可以指定要输入的数字是短数字,则Java不必强制转换它-这是一个假设,如果我输入错误,请更正我。我通常会自己搜索这个问题,但是我什至不知道这种数字规范叫什么。

Answers:


174

对于long(例如39832L),float(例如2.4f)和double(例如-7.832d)。

如果没有后缀,并且是整数类型(例如5623),则假定为int。如果它不是整数类型(例如3.14159),则假定为double

在其他情况下(byteshortchar),你需要投,因为没有具体的后缀。

Java规范允许上部和下部壳体的后缀,但是上壳体版本为longs的优选的,因为上壳体L不太容易混淆以数字1比下壳体l

详细信息请参见JLS第3.10节(请参阅的定义IntegerTypeSuffix)。


9
逾期报名:消除歧义的潜在来源始终是好的,我不反对 ......但我相信,如果你发现自己困惑1l0O(等),你的优先级是设置字体权(如果你能),然后担心不要错过Shift键。
davidcesarino'4

@SimonNickerson我有一个后缀问题...如果我宣布一个象变量:long _lo = 30;而不是30L这是否意味着我的变量将被转换成浮动?或者,即使声明为长时_lo = _lo + 2.77_lo将其转换为float
luigi7up 2012年

不,这里不涉及花车。在第一种情况下,30是,int它将通过扩展转换自动转换为long。在第二种情况下,您的陈述是非法的。您必须明确地将右手的位置变长,例如_lo = (long) (_lo + 2.77)
Simon Nickerson

4
@DavidCesarino更改字体可以为您解决歧义-在您将其正确设置的特定编辑器中。将l更改为L可以解决每个人(包括您自己)在使用其他Editor,IDE,在Web上查看源代码(审阅工具,存储库等)时可能曾经读过您代码的歧义的问题。恕我直言,优先事项是不要错过Shift键。顺便说一句。你推荐什么字体?我喜欢等宽字体,这几乎是我所见过的所有编辑器,CLI等中的默认字体l,并且这种字体和10O)分别非常相似。
dingalapadum

1
@dingalapadum正如我说的,您是对的。消除歧义的来源绝对是正确的事情。我只是说过,您应该尽量不要使用任何容易使它们出错的编辑器。换句话说,防御性编码的旧建议是,但不依赖于此。关于字体,它非常个性化,但是我总是尽可能使用Deja Vu Sans Mono,因为1)它是等距的;2)字符之间没有歧义;3)我喜欢它的形状,优美而优美,几乎就像一种好的,可读的无衬线字体(其他好的编程字体感觉太“金属”恕我直言)。
davidcesarino

13

我希望你不会介意轻微的切线,但认为你可能有兴趣知道,除了F(浮法), D(双),和L(长),一个已经提出添加后缀byteshort- YS分别。当对字节(或短)数组使用文字语法时,这将消除对转换为字节的需要。引用提案中的示例:

主要好处:如果采纳该建议,为什么平台会更好?

像这样的代码

 byte[] stuff = { 0x00, 0x7F, (byte)0x80,  (byte)0xFF};

可以重新编码为

 byte[] ufum7 = { 0x00y, 0x7Fy, 0x80y, 0xFFy };

Joe Darcy正在监督Java 7的Project Coin,他的博客一直是跟踪这些建议的简便方法。


那就太好了……我一直发现所有演员表都真令人讨厌
jbu

我认为这并没有使它成为Java7。是否可以在将来的更新或Java 8中使用它呢?
2013年

@crush我尝试在几个月前对其进行调查,据我所知,该提案已被放弃。我们确实在数字文字中获得了_,并在0b二进制文字中获得了前缀。哎呀
erickson

这项提议可能是在kotlin而不是Java上实现的,因为oracle不想让社区告诉他们如何工作...我们在2018年,但仍然对此提案一无所知,可悲的是
JoelBonetR

11

默认情况下,Java编译器会将任何整数原始数据类型(字节,短型,整型,长型)视为整型。对于byteshort,只要分配给它们的值在其范围内,就没有问题,也不需要后缀。如果分配给byteshort的值超出其范围,则需要显式类型转换。

例如:

byte b = 130; // CE: range is exceeding.

克服这种执行类型转换。

byte b = (byte)130; //valid, but chances of losing data is there.

在长数据类型的情况下,它可以毫不费力地接受整数值。假设我们分配像

Long l = 2147483647; //which is max value of int

在这种情况下,不需要像L / l这样的后缀。默认情况下,java编译器认为int类型的值为2147483647。内部类型转换由编译器完成,并且int自动提升为Long类型。

Long l = 2147483648; //CE: value is treated as int but out of range 

在这里,我们需要将后缀设为L,以将文字2147483648视为java编译器的long类型。

所以最后

Long l = 2147483648L;// works fine.


1

似乎这些内容会很好,因为(我假设)如果您可以指定要输入的数字很短,那么Java不必强制转换

由于文字的解析是在编译时进行的,因此这与性能绝对无关。具有shortbyte后缀很好的唯一原因是它导致更紧凑的代码。


0

要了解为什么有必要区分intlong文字,请考虑:

long l = -1 >>> 1;

int a = -1;
long l = a >>> 1;

现在,正如您正确预期的那样,两个代码片段都为variable提供了相同的值l。如果不能够区分intlong文字,是什么解释-1 >>> 1

-1L >>> 1 // ?

要么

(int)-1 >>> 1 // ?

因此,即使数字在公共范围内,我们也需要指定类型。如果默认值随字面量的大小而变化,则表达式的解释将发生奇怪的变化,仅是改变数字。

这不会发生的byteshort而且char因为他们是执行算术和位操作之前一直提倡。可以说它们应该是整数类型的后缀,例如用于数组初始化表达式,但是没有。float使用后缀fdouble d。其他文字具有明确的类型,其中有一个特殊类型null


我真的会对您过去的意思感兴趣。在这两种情况下,我都得到2147483647,但我不明白为什么我应该期待其他事情。
令人难以置信的Jan

@TheincredibleJan您应该正确地期望Integer.MAX_VALUE,但是,如果没有办法区分intlong文字,那将是模棱两可的。/我不记得这个问题,但是无论如何都已经澄清了我的答案。
汤姆·哈特芬
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.