2015-12-09 41 views
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; 
    } 

} 

对我来说,这看起来很模糊。如何区分int和long?

一个整数范围内的数字可以是一个long,用num的声明来演示。

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

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

我首先想到,如果它在int范围内,它会自动将其视为一个int,并且当它超出该范围时,它将被用作long。 但是,用我的第二个参数,它不会通过,除非我放置L.它说它不在int的范围内。

有人可以给这个明确的规则吗?

回答

3

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

如果它超出了int的范围,这是一个编译错误。

声明NUM时

,这是没有必要的

您可以将文字到长变量int类型,因为没有信息丢失。

+0

我明白了。所以除非有后缀,默认情况下是int? –

+0

并带有小数点,是默认的双精度型吗? –

+0

@JohnDoe是的。类似地,带浮点的文字(如1.0)是双精度的。 – Eran

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后缀,默认整数值将是一个integer
  • 如果没有d后缀,默认十进制值会一个double
1

引用Java语言规范:

3.10.1. Integer Literals

字面一个整数是long类型的,如果它是与ASCII字母Ll(ELL)后缀; 否则它是int§4.2.1)类型。

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

所以,一个整数是int除非L结束。由于1000000000000是一个int太大,必须末与L,或者你会得到一个编译错误(“int类型的字面1000000000000超出范围”)

3.10.2. Floating-Point Literals

浮点字面是float类型的,如果它是与ASCII字母Ff后缀; ,否则其类型为double,它可以选择性地以ASCII字母Dd§4.2.3)作为后缀。

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

5.1.2. Widening Primitive Conversion

  • intlongfloat,或double

  • floatdouble

因此,如果需要,编译器会默认扩展(转换)int值到long,

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

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

0

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

如果您调用方法,参数的实际(编译时)类型将决定调用哪个重载方法。如果可以使用给定的类型调用多个重载方法,则将采用最具体的方法。 (关于准确的规则,请阅读JLS的Section 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 
1

几个点,我想起了你的问题,
1.声明一个变量长那么就没有必要把L用变量值
2.如果要传递一个硬编码的数字文字,你把L放在最后使其变长,否则所有的数值被视为int(如果没有正确的后缀)
3.你可以通过一个int来代替长参数(自动扩展将会发生)
4.你在没有明确铸造的情况下不能通过狭窄的类型
5.参数转换on是通过显式强制转换和自动加宽而不考虑数值的大小。

对于下面的代码示例 - “内部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 "); 
    } 

希望它能帮助!