为什么Java整数文本的默认类型是int而不是long?

为什么Java整数文本的默认类型是int而不是long?,java,integer,literals,Java,Integer,Literals,我不明白为什么Java整数文本默认为int,而不是long。这似乎造成了不必要的混乱 首先,它要求程序员在为超过最大int大小(2147483647)的long赋值时采用特殊语法(将“L”附加到文字) 其次,当使用Long包装类时,程序员必须始终使用Long文字符号,如中所述 第三,考虑到从int文本到“更窄”数据类型(short和byte)的隐式转换在所有情况下都能正常工作(据我所知),简单地将所有整数文本类型变长似乎是显而易见的解决方案。。。正确的?这难道不能完全消除在特殊情况下对整数文本追

我不明白为什么Java整数文本默认为
int
,而不是
long
。这似乎造成了不必要的混乱

首先,它要求程序员在为超过最大
int
大小(2147483647)的
long
赋值时采用特殊语法(将“L”附加到文字)

其次,当使用
Long
包装类时,程序员必须始终使用
Long
文字符号,如中所述

第三,考虑到从
int
文本到“更窄”数据类型(
short
byte
)的隐式转换在所有情况下都能正常工作(据我所知),简单地将所有整数文本类型
变长
似乎是显而易见的解决方案。。。正确的?这难道不能完全消除在特殊情况下对整数文本追加“L”的这种奇怪系统的需要吗

Long x = 250;
那不行。Java使用自动装箱,自动将对象代表类强制转换为基元类型。至于其他数字,int只是使用的主要数字类型。long,至少在我最常用的情况下,只用于日期和时间。另一方面,默认情况下,整数用于其他所有内容

如果你真的想了解具体情况,我相信这会让你的jimmies更受欢迎:

float pi = 3.14; // Does not compile.
float pi = 3.14F; // Compiles

在这种情况下,当涉及十进制数时,double优先

我认为将int文本设置为不需要类型指示的文本的原因是int是普通整数类型。类似地,double是正常的浮点类型。这个想法似乎是通过默认为最常见的类型来限制需要类型指示的文本数量。

我认为你是对的,
long
将是今天更好的默认值。早在1995年,
long
可能太长而不能作为默认值。

速度

只使用所需的尺寸,可以提高效率。整数适用于-2^31到2^31之间的数字。如果在int就足够的地方使用long,则会降低代码的速度。例如,此代码在我的机器上以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 ");
  }   
}
公共类问题005{
私有静态布尔值可由ALL划分(长n,长上限){
用于(长i=1;i<天花板;i++)
如果(n%i!=0)
返回false;
返回true;
}
公共静态长FindSalletMultiple(长天花板){
长数=1;
而(!IsDivisible ByAll(数字、上限))
数字++;
返回号码;
}
}
公共类秒表{
私人最终长期启动;
公众秒表{
start=System.currentTimeMillis();
}
公共双elapsedTime(){
long now=System.currentTimeMillis();
返回(现在-开始)/1000.0;
}
}
公共班机{
公共静态void main(字符串[]args){
秒表秒表005=新秒表();
长高倍数=20;
long findsmalletmultipleoutput=findsmalletmultiple(最高倍数);
double FindSalestMultipleTime=stopwatch005.elapsedTime();
System.out.println(“问题#005”);
System.out.println(“======================”);
System.out.print(“数字的倍数1-”+最高倍数+”为=);
系统输出打印(FindSallestMultipleOutput);
System.out.println(“时间为“+FindSalestMultipleTime+”秒。\n”);
}   
}
更改为使用int:
公共类问题005{
私有静态布尔值是可划分的(整数n,整数上限){
对于(int i=1;i<天花板;i++)
如果(n%i!=0)
返回false;
返回true;
}
公共静态int FindSalletMultiple(int天花板){
整数=1;
而(!IsDivisible ByAll(数字、上限))
数字++;
返回号码;
}
}

int
作为默认文本的一个可能原因是,使用
lont
可能会导致在多线程应用程序中难以检测到错误,如中所述

就Java编程语言内存模型而言,对非易失性long或double值的一次写入被视为两次单独的写入:每32位的一半写入一次。这可能导致线程在一次写入中看到64位值的前32位,在另一次写入中看到第二个32位

此行为由design1设计,并在中进行了编码

首先,请注意,这与(有效)整型文字提升为长值的原因无关。相反,这与以下各项的规格有关:

如果十六进制、八进制或二进制int文本不适合32位,则为编译时错误

最小和最大有符号32位整数值分别为-2147483648和2147483647



1我不想猜测为什么它是这样工作的,像C#这样的语言有不同的规则。

一种语言可能要求所有整数运算都不会溢出,如果中间结果是用最长的整数类型计算的,就好像它们是。在这种语言中,如果以L开头的变量是64位,以W开头的变量是32位,以H开头的变量是16位,则表达式如下

L1 = W1*W2;
W3 = (W1+W2) >> 1
将以避免溢出的方式进行计算,但是

W4 = W1+W2
W5 = (H1*H2) >> 1
将使用32位数学进行求值(因为随后发生的任何溢出都会随着W4的赋值而发生,即使中间结果被求值为32位),以及如下表达式

W4 = W1+W2
W5 = (H1*H2) >> 1
由于结果不能溢出32位值,因此可以计算为32位

这种语言在大多数情况下都非常有效,因为编译器通常不难确定每个子表达式的最大相关整数大小。用这种语言
W5 = (H1*H2) >> 1