在Java中转换为int和intValue()方法之间的区别

时间:2015-04-14 15:03:30

标签: java

我有一个需要转换为整数的long值。当我使用强制转换时,时间整数值给出一个负值,这是不期望的。但是当我在intValue()中使用Long方法时,会出现预期结果。

我想知道转换和使用intValue()方法

的区别
  1. 投射示例

    int days = (int) ((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));

  2. intValue示例

    int days = ((Long) ((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24))).intValue();

  3. 编辑:更详细说明示例以显示减值而不会出现溢出,如评论中所示。在转换之前,结果是27.当转换时,值变为-22。但是如果使用intValue方法,结果是27。

    代码

                System.out.println("nextDeliveryDate = " + nextDeliveryDate);
                System.out.println("nextDeliveryDate.getTime() = " + nextDeliveryDate.getTime());
                System.out.println("expectedDeliveryDate = " + expectedDeliveryDate);
                System.out.println("expectedDeliveryDate.getTime() = " + expectedDeliveryDate.getTime());
                System.out.println("nextDeliveryDate.getTime() - expectedDeliveryDate.getTime() = " + (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()));
                System.out.println("(nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24) = " + (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24));
                System.out.println("((int) (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24)) = " + ((int) (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24)));
                System.out.println("((Long) ((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24))).intValue() = " + ((Long) ((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24))).intValue());
    

    结果

    Info: nextDeliveryDate = Thu May 14 00:00:00 IST 2015
    Info: nextDeliveryDate.getTime() = 1431541800000
    Info: expectedDeliveryDate = Fri Apr 17 00:00:00 IST 2015
    Info: expectedDeliveryDate.getTime() = 1429209000000
    Info: nextDeliveryDate.getTime() - expectedDeliveryDate.getTime() = 2332800000
    Info: (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24) = 27
    Info: ((int) (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24)) = -22
    Info: ((Long) ((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24))).intValue() = 27
    

4 个答案:

答案 0 :(得分:5)

你可能会遇到int溢出。如果toDate.getTime()fromDate.getTime()之间的差异大于2.147 bilion(即Integer.MAX_VALUE),则无法将其表示为整数,它只会换行并更改达到最低价值 - 例如Integer.MAX_VALUE + 100会给你带来负面结果。

你应该首先对long进行所有操作,直到你确定它足够小,可以在没有溢出的情况下强制转换为int。我认为你的例子都是正确的,第一个肯定比另一个更清楚。

另外,请记住像1000 * 60 * 60 * 24这样的表达式是整数,它们也可能溢出。例如,一个月内的毫秒数为31 * 24 * 3600 * 1000,但是这样写的它会返回-1616567296

编辑:让我解释您在编辑中附加的输出:

Info: nextDeliveryDate.getTime() - expectedDeliveryDate.getTime() = 2332800000
Info: (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24) = 27
Info: ((int) (nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24)) = -22
Info: ((Long) ((nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()) / (1000 * 60 * 60 * 24))).intValue() = 27

我还会将nextDeliveryDate.getTime() - expectedDeliveryDate.getTime()称为x。所以我们可以将它声明为long x = 2332800000(声明int将给出编译错误,因为它太大而无法保存为4个字节)。

在第一行中,您有x / somethingsomething是一个int且x很长,因此something将转换为long,最终结果很长。

在第二行中,您有((int) x) / something,所以2332800000长整数转换为整数,给出了-1962167296,然后您有-1962167296 / something

在你的最后一行中,你有(Long) (x / something),这与第一行实际上是相同的。

答案 1 :(得分:4)

我不认为您的结果应该有所不同,因为这是Long.intValue()方法的作用:

public int intValue() {
    return (int)value;
}

在这两行之间你的控制流是不对的。

您可以尝试以下测试:

Calendar now = Calendar.getInstance();
Date fromDate = now.getTime();
now.add(Calendar.YEAR, 10);
Date toDate = now.getTime();

System.out.println("line 0: " + (toDate.getTime() - fromDate.getTime()));
System.out.println("line 1: " + (int)(toDate.getTime() - fromDate.getTime()));
System.out.println("line 2: " + new Long((toDate.getTime() - fromDate.getTime())).intValue());

int days = (int) ((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));

System.out.println("line 3: " + days);

days = ((Long) ((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24))).intValue();

System.out.println("line 4: " + days);

答案 2 :(得分:2)

没有区别,这段代码

public static void main(String[] args) {
    System.out.println((int) (21470000000l));
    System.out.println((int) ((Long)21470000000l).intValue());
}

有这个输出:

-4836480
-4836480

因此,您在toDatefromDate中有不同的值。

如果该值超过整数的MAX,则永远不会得到“预期”结果,因为它不适合那里。

答案 3 :(得分:2)

首先,解释一下Java中的转换为int和IntValue()方法之间的区别。

IntValue()整数类(和其他包装类)中的方法。

IntValue将做的是获取整数并将其作为int类型返回。

请注意,int是原始数据类型,Integer是保存此数据类型的类。它就像一个包装器,因为有些数据结构无法保存原始数据类型。 See this SO question for more info

基本上:

  

将int转换为Integer称为装箱。

     

将Integer转换为int称为取消装箱

正如我提出的SO问题所述。

然而,就您的示例而言,由于涉及的类型,这有点不同。不同之处在于,为了准确性,您将所有操作作为Long数据类型执行,其中包含的数字比int更多,然后仅将其转换为int。所以你的IntValue()方法来自long数据类型Java7 docs mention of it's use。基本上它只是将它从long更改为int,仍然可能导致溢出

请注意Long是原始数据类型long的包装类(其中原始数据类型没有IntValue()方法)

因此,您获得的值的差异可能是因为当您从Long执行简单转换时 - > int原始数据类型,没有溢出。

我建议您使用不会更改的非常大的数字来测试您的代码(与日期,时间不同,每次获取时都不同)

解决溢出问题

您可能也会感兴趣如何安全地将一个long转换为java中的int ,如this SO question中所述,作为处理溢出可能性的替代解决方案。

我建议的另一种方法是先将降低精度(因此你会失去精度)到一个足够安全的值(并且足够精确),然后再将其转换回int以供使用。 / p>

或者,使用 BigIntegers ,它们是不可变的任意精度整数。 see the the documentation on this classthis SO Q&A on how to use it。它肯定会增加代码的复杂性,因为它们是不可变的。

This other SO question提供了很好的解决方案,可以为intslongs中的检测溢出提供更好的方法,我也建议这样做。