【问题标题】:How to distinguish between int and long?如何区分int和long?
【发布时间】:2015-12-09 08:00:34
【问题描述】:
 public class NewMain
 {
     public static void main(String[] args)
     {
         long num = 100;
         System.out.println(xMethod(5,1000000000000L));

     }

     public static int xMethod(int n, long x)
     {
         System.out.println("int, long");
         return n;
     }

     public static long xMethod(long n, long x)
     {
         System.out.println("long, long");
         return n;
     }

 }

对我来说,这看起来很模棱两可。

整数范围内的数字可以是long,用num的声明来说明。

我很好奇如果我有两个方法和两个不同的参数会发生什么。

显然,在编写参数时,数字必须在末尾有一个 L 以表示它是一个 long,而在声明 num 时,这不是必需的。 这是为什么呢?

我首先想到的是,如果它在 int 的范围内,它会自动将其视为 int,当超出该范围时,它将被用作 long。 但是,对于我的第二个参数,除非我输入 L,否则它不会通过。它说它不在 int 的范围内。

有人可以对此给出一些明确的规则吗?

【问题讨论】:

    标签: java int long-integer


    【解决方案1】:

    没有小数点的数字文字总是被视为int,除非它有一个指定的后缀(例如 L)。

    如果超出 int 范围,则为编译错误。

    在声明 num 时,这不是必需的

    您可以将 int 文字分配给 long 变量,因为不会丢失信息。

    【讨论】:

    • 我明白了。所以除非有后缀,否则默认是int?
    • 带小数的,默认是双精度的吗?
    • @JohnDoe 是的。同样,带有浮点数的文字(例如 1.0)是双精度数。
    【解决方案2】:

    引用 Java 语言规范:

    3.10.1. Integer Literals

    如果整数文字以 ASCII 字母 Ll (ell) 为后缀,则其类型为 long否则它的类型为int (§4.2.1)。

    首选后缀L,因为字母l(ell)通常很难与数字1(一)区分开来。

    因此,整数是int,除非以L 结尾。由于1000000000000 对于int 来说太大了,它必须L 结尾,否则会出现编译错误(“int 类型的文字1000000000000 是超出范围").

    3.10.2. Floating-Point Literals

    如果浮点文字以 ASCII 字母 Ff 为后缀,则其类型为 float否则其类型为double,并且可以选择以ASCII 字母Dd (§4.2.3) 作为后缀。

    因此,十进制数是 double,除非以 f 结尾。

    5.1.2. Widening Primitive Conversion

    • intlongfloatdouble

    • floatdouble

    因此,如果需要,编译器会默默地将int 的值扩大(转换)为long

    在您的情况下,编译器更喜欢第一种方法,因为它可以在没有任何转换的情况下调用。

    如果第一个方法不存在,则在将第一个参数隐式转换为long 之后调用第二个方法。

    【讨论】:

      【解决方案3】:

      对于您的问题,我想到了几点,
      1. 变量声明为long,那么变量值不需要放L
      2. 如果您传递的是硬编码数字文字,请将 L 放在末尾以使其变长,否则所有数值都将被视为 int(如果没有正确后缀)
      3.您可以传递一个int来代替long参数(会发生自动加宽)
      4. 如果没有显式强制转换,您不能通过窄类型代替宽类型
      5. 参数转换要么通过显式转换,要么通过自动加宽,不考虑数值大小。

      对于下面的代码示例 - 由于自动加宽并且没有private static void aMethod(int a , int b),将打印“Inside INT LONG”

      public class IntVsLons {
      
          public static void main(String[] args) {
              // TODO Auto-generated method stub
      
              int a =100;
              long b=200;
      
              aMethod(a,a);
      
              }
      
          /*
          private static void aMethod(int a , int b){
              System.out.println("Inside INT  INT  ");
          }
          */
      
          private static void aMethod(int a , long b){
              System.out.println("Inside INT  LONG ");
          }
      
          private static void aMethod(long a, long b ){
              System.out.println("Inside LONG LONG ");
          }
      

      希望对你有帮助!!

      【讨论】:

        【解决方案4】:

        您的担忧是有道理的。看看这个场景:

        public static void methodX(long x, int y){
        
        }
        public static void methodX(int x, long y){
        
        }
        

        在这种情况下,如果你调用以下命令,它会给你不同的结果:

        methodX(123, 123);    //Compilation error (reference to methodX is ambiguous)
        methodX(123L, 123);   //Ok!
        methodX(123, 123L);   //Ok!
        

        第一次调用会给你错误,因为默认情况下没有后缀(你创建一个整数),它能够适应两个重载方法。


        一些附加信息

        • 没有l的后缀,默认的整数值为integer
        • 如果没有d 后缀,则默认十进制值为double

        【讨论】:

          【解决方案5】:

          不带小数点且不带后缀的数字文字,例如 42100 始终是 int 类型。要使其成为long,您必须添加一个后缀:42L100L

          如果你调用一个方法,参数的实际(编译时)类型决定了调用哪个重载方法。如果可以使用给定类型调用多个重载方法,则将采用最具体的方法。 (有关确切规则,请阅读 JLS 的第 15.2 节。)因此,如果第一个参数是 int,则将调用第一个方法重载,因为 int 更具体为 long .

          xMethod(1, 1)  --> xMethod(int n, long x) is called
          xMethod(1L, 1) --> xMethod(long n, long x) is called
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-01-27
            • 1970-01-01
            • 2020-09-03
            • 1970-01-01
            • 1970-01-01
            • 2016-12-16
            • 1970-01-01
            • 2017-09-10
            相关资源
            最近更新 更多