如何区分int和long数据类型?

3
 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 的范围内。
有人能给出一些清晰的规则吗?
5个回答

3

如果一个数字字面量没有小数点,则始终被视为 int,除非它有指定其他类型的后缀(例如 L)。

如果超出了 int 的范围,则会出现编译错误。

在声明 num 时,这是不必要的。

您可以将 int 字面量分配给 long 变量,因为没有信息丢失。


我明白了。所以除非有后缀,否则默认为int类型? - John Doe
而且在编程中,有一个小数点的情况下,默认是双精度浮点数吗? - John Doe
@JohnDoe 是的。同样,带有浮点数(例如1.0)的字面量是double类型。 - Eran

1
我的想法与您的问题有关,如下:
1. 如果声明变量为long,则不需要在变量值后加上L
2. 如果传递硬编码数值文字,您需要在其末尾添加L以使其成为长整型,否则所有数字值都将被视为int(如果未正确添加后缀)
3. 您可以在长整型参数的位置传递int(会自动发生扩展)
4. 您不能在更宽的类型的位置上传递狭窄的类型而不进行显式转换
5. 参数转换是通过显式转换和自动扩展实现的,而不考虑数字值的大小。
对于下面的代码示例 - "Inside INT LONG"将被打印出来,因为会自动扩展并且没有 private static void aMethod(int a, int b)
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 ");
    }

希望它有所帮助!!

1

引用Java语言规范:

3.10.1. 整数字面量

如果一个整数字面量后缀带有ASCII字母Ll(小写L),则它的类型为long否则它的类型为int§4.2.1)。

后缀L更受欢迎,因为字母l(小写L)往往难以与数字1(一)区分开来。

所以,一个整数是一个int,除非以L结尾。由于1000000000000太大了,无法用int表示,它必须L结尾,否则会得到编译错误(“类型为int的文字量1000000000000超出范围”)

3.10.2. 浮点型字面值

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

因此,十进制数是double类型,除非以f结尾。
引用: 5.1.2. 扩展原始类型转换
  • int 转换为 longfloatdouble

  • float 转换为 double

因此,如果需要的话,编译器将默默地扩展(转换)int值为long
在您的情况下,编译器更喜欢第一种方法,因为它可以在不进行任何转换的情况下调用。
如果第一种方法不存在,则在将第一个参数隐式转换为long后将调用第二种方法。

0

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

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,默认的整数值将是一个整型
  • 没有后缀d,默认的小数值将是一个双精度浮点型

0

一个没有小数点和后缀的数字字面量,例如42100,总是属于类型int。要使它成为long,必须添加后缀:42L100L

如果调用一个方法,实际(编译时)参数的类型决定调用哪个重载方法。如果有多个重载方法可以使用给定的类型进行调用,则将选择最具体的方法。(有关确切规则,请阅读JLS的第15.2节。)因此,在您的情况下,如果第一个参数是int,将调用第一个方法重载,因为intlong更具体。

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

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