我很困惑,为什么Java的整数常量默认为int
,而不是long
。 这似乎引起不必要的混乱。
首先,它需要采取特殊的语法程序员分配一个值的时候(加上“L”,以文字) long
超过最大int
大小(2147483647)。
long x = 2147483647; // Compiles
long y = 2147483648; // Does not compile
long z = 2147483648L; // Compiles
其次,使用时Long
包装类,程序员必须始终使用long
的文字符号在解释这太问题 。
Long x = 250; // Does not compile
Long y = 250L; // Compiles
第三,考虑到从隐式转换int
文字为“窄”的数据类型( short
和byte
)适用于所有情况就好了(我知道的),似乎只是使所有整数文字输入long
将是显而易见的解决方案... 对? 这是不是完全删除在特殊情况下附加“L”至整数文字的这种古怪的系统的需要?
此行为是设计1,并在被编纂JLS:Java语言规范 。
首先,请注意,这是不相关的加宽这就是为什么(有效)整数文本提升为长期的价值。 相反,这是关系到的非常规范INT文字 :
它是一个编译时间错误,如果以十六进制,八进制,或二进制INT字面不以32位适合。
最小和最大的带符号的32位整数值分别为-2147483648和2147483647。
1我不去猜测,为什么是这样工作的,而像C#语言有不同的规则。
速度
您可以通过只使用你需要的大小有效率的提高。 一个int是细从-2 ^ 31〜2 ^ 31的数字。 如果您使用的是长,其中一个int就足够了,你放慢你的代码。 例如,下面的代码运行在我的机器上7.116秒。 通过将其切换到使用INT,我减少了运行时间,以我的机器上3.74秒:
public class Problem005 {
private static boolean isDivisibleByAll(long n, long ceiling) {
for (long i = 1; i < ceiling; i++)
if (n % i != 0)
return false;
return true;
}
public static long findSmallestMultiple (long ceiling) {
long number = 1;
while (!isDivisibleByAll(number, ceiling))
number++;
return number;
}
}
public class Stopwatch {
private final long start;
public Stopwatch() {
start = System.currentTimeMillis();
}
public double elapsedTime() {
long now = System.currentTimeMillis();
return (now - start) / 1000.0;
}
}
public class Main {
public static void main(String[] args) {
Stopwatch stopwatch005 = new Stopwatch();
long highestMultiple = 20;
long findSmallestMultipleOutput = findSmallestMultiple(highestMultiple);
double findSmallestMultipleTime = stopwatch005.elapsedTime();
System.out.println("Problem #005");
System.out.println("============");
System.out.print("The multiple of the numbers 1-" + highestMultiple + " is = ");
System.out.print(findSmallestMultipleOutput);
System.out.println(" with a time of " + findSmallestMultipleTime + " seconds.\n ");
}
}
改为使用int:
public class Problem005 {
private static boolean isDivisibleByAll(int n, int ceiling) {
for (int i = 1; i < ceiling; i++)
if (n % i != 0)
return false;
return true;
}
public static int findSmallestMultiple (int ceiling) {
int number = 1;
while (!isDivisibleByAll(number, ceiling))
number++;
return number;
}
}
其中之一是,可能的原因int
是默认的文字是用lont
可能导致难以察觉的多线程应用程序错误在指定JLS 17.7的双和长非原子处理 。
对于Java程序设计语言存储器模型的目的,对非易失性长或双值的单个写入被视为两个单独的写操作:一个用于每个32位的一半。 这可以导致其中线程看到一个64位值的第一32位从一个写操作,并且从另一写第二32位的情况。
我认为你是对的, long
会有今天更好的默认值。 早在1995年, long
可能是太长时间是默认的。
为了
Long x = 250;
这是行不通的。 Java使用自动装箱,其从对象代表类自动转换到基本类型。 至于其他的人,诠释的只是主号码类型使用。 多头,以及至少对我最经常使用它们,仅用于日期和时间。 在另一方面整数其他一切默认情况下使用。
如果你真的想进入细节,我敢肯定,这将沙沙您糖条更多:
float pi = 3.14; // Does not compile.
float pi = 3.14F; // Compiles
在这种情况下,采用双优先级时,这牵涉到小数。
我想制作INT文字不需要类型指示的那些原因是INT旨在正常整数类型。 类似地,双为正常浮点型。 这个想法似乎是限制那些需要被默认为最常见的类型的类型指示文字的数量。
这将有可能对语言要求,这将如果中间结果计算不溢最长整数类型,就好像他们都是整数运算。 在这样的语言中,如果开始与L-变量是64位,那些具有W为32位,而那些用H是16位,像表达式
L1 = W1*W2;
W3 = (W1+W2) >> 1
将以这样的方式进行评价,以避免溢出,但像的表达
W4 = W1+W2
将使用32位数学(因为这将发生,然后将与分配到W4即使中间结果被评估为32个比特发生的任何溢)进行评价,以及类似的表达
W5 = (H1*H2) >> 1
为32位可评价因为其结果可能不会溢出32位值。
这种语言可能是在大多数情况下非常有效,因为它一般不会很难编译器,以确定每个子表达式的最大整数相关的大小。 在这样的一种语言,它不会有问题数字文字是否是一个“长”或“INT”,因为编译器会更感兴趣的数值。
但是在Java中,不同尺寸的数字文字有不同的语义。 如果一个乘以一个int
由恒定128, int
必须不超过16777215要不然会发生溢出变大。 如果一个乘以int
一个常数128L
,结果只可以存储某个地方,可以接受long
。
文章来源: Why is the default type of Java integer literals int instead of long? [closed]