Day10-33.Casting operators

本文详细介绍了Java中的类型转换概念,包括自动类型提升、窄化转换和扩展转换等,并通过示例解释了数值类型转换时的截尾与舍入处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类型转换操作符


类型转换(cast) 的原意是“模型铸造”。在适当的时候,Java会将一种数据类型自动转换成另一种。

例如,假设我们为某浮点变量赋以一个整数值,编译器会将int自动转换成float。

类型转换运算允许我们显式地进行这种类型的转换,或者在不能自动进行转换的时候强制进行类型转换。

要想执行类型转换,需要将希望得到的数据类型置于圆括号内,放在要进行类型转换的值得左边,可以在下面的示例中看到它:


//: operators/Casting.java

public class Casting {
  public static void main(String[] args) {
    int i = 200;
    long lng = (long)i;
    lng = i; // "Widening," so cast not really required
    long lng2 = (long)200;
    lng2 = 200;
    // A "narrowing conversion":
    i = (int)lng2; // Cast required
  }
} ///:~



正如所看到的,既可以对数值进行类型转换,亦可对变量进行类型转换。

请注意,这里可能会引入”多余的“转型,例如,编译器在必要的时候回自动进行int值到long值得提升。

但是你仍然可以做这样”多余的“事,以提醒自己需要留意,也可以使代码更清楚。

在其他情况下,可能只有先进行类型转换,代码编译才能通过。

在C和C++中,类型转换有时会让人头痛。

但是在Java中,类型转换则是一种比较安全的操作。

然而,如果要执行一种名为窄化转化(narrowing conversion)的操作(也就是说,将能容纳更多信息的数据类型转换成无法容纳那么多信息的类型),就有可能面临信息丢失的危险。

此时,编译器会强制我们进行类型转换,这实际上是说:“这可能是一件危险的事情,如果无论如何要这么做,必须显式地进行类型转换”。

而对于扩展转换(widening conversion),则不必显式地进行类型转换,因为新类型肯定能容纳原来类型的信息,不会造成任何信息的丢失。

Java允许我们把任何基本数据类型转换成别的基本数据类型,但布尔型除外,后者根本不允许进行任何类型的转换处理。

“类”数据类型不允许进行类型转换。

为了将一种类转换成另一种,必须采用特殊的方法(本书后面会讲到,对象可以在其所属类型的类族之间可以进行类型转换;

例如,“橡树”可转型为“树”;反之亦然。但不能把它转换成类族以外的类型,如“岩石”)。



Truncation and rounding 

截尾和舍入


在执行窄化转换时,必须注意截尾与舍入问题。

例如,如果价格一个浮点值转换为整型值,Java会如何处理呢?

例如将29.7转换为int,结果是30还是29?在下面的示例中可以找到答案:


//: operators/CastingNumbers.java
// What happens when you cast a float
// or double to an integral value?
import static net.mindview.util.Print.*;

public class CastingNumbers {
  public static void main(String[] args) {
    double above = 0.7, below = 0.4;
    float fabove = 0.7f, fbelow = 0.4f;
    print("(int)above: " + (int)above);
    print("(int)below: " + (int)below);
    print("(int)fabove: " + (int)fabove);
    print("(int)fbelow: " + (int)fbelow);
  }
} /* Output:
(int)above: 0
(int)below: 0
(int)fabove: 0
(int)fbelow: 0
*///:~


因此答案是在将float或double转型为整型值时,总是对该数字执行截尾。

如果想要得到舍入的结果,就需要使用java.lang.Math中的round()方法:

//: operators/RoundingNumbers.java
// Rounding floats and doubles.
import static net.mindview.util.Print.*;

public class RoundingNumbers {
  public static void main(String[] args) {
    double above = 0.7, below = 0.4;
    float fabove = 0.7f, fbelow = 0.4f;
    print("Math.round(above): " + Math.round(above));
    print("Math.round(below): " + Math.round(below));
    print("Math.round(fabove): " + Math.round(fabove));
    print("Math.round(fbelow): " + Math.round(fbelow));
  }
} /* Output:
Math.round(above): 1
Math.round(below): 0
Math.round(fabove): 1
Math.round(fbelow): 0
*///:~
由于round()是java.lang的一部分,因此在使用它时不需要额外地导入。

Promotion 

提升


如果对基本数据类型执行算数运算或按位运算,大家会发现,只要类型比int小(即char/byte或者short),

那么在运算之前,这些值会自动转换成int。

这样一来,最终生成的结果就是int类型。如果想把结果赋值给较小的类型,就必须使用类型转换

(既然把结果赋给了较小的类型,就可能出现信息丢失)。

通常,表达式中出现的最大的数据类型决定了表达式最终结果的数据类型。

如果将一个float值与一个double值想乘,结果就是double;

如果将一个int和一个long值相加,则结果为long。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值