Java 强制类型转换(学习 Java 编程语言 044)

将一个类型强制转换成另外一个类型的过程被称为强制类型转换。Java 程序设计语言提供了一种专门用于进行强制类型转换的表示法。
double x = 3.405;
int nx = (int) x;
将表达式 x 的值转换成整数类型,舍弃了小数部分。

正像有时候需要将浮点数转换成整数一样,有时候也可能需要将某个类的对象引用转换成另外一个类的对象引用。要完成对象引用的强制类型转换,转换语法与数值表达式的强制类型转换类似,仅需要用一对圆括号将目标类名括起来,并放置在需要转换的对象引用之前就可以了。

public class Manager extends Employee {
    ...
}
Employee[] staff = new Employee[3];
staff[0] = new Manager("Carl Cracker", 75000, 1987, 12, 15);
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);

// 强制类型转换
Manager boss = (Manager)staff[0];

进行强制类型转换的唯一原因是: 要在暂时忽视对象的实际类型之后使用对象的全部功能。例如,由于某些元素是普通员工,所以 staff 数组必须是 Employee 对象的数组。我们需要将数组中引用经理的元素复原成 Manage 对象,以便能够访问新增加的所有变量。

在 Java中,每个对象变量都有一个类型。类型描述了这个变量所引用的以及能够引用的对象类型。例如,staff[i] 引用了一个 Employee 对象(因此它还可以引用 Manager 对象)。

将一个值存入变量时,编译器将检查你是否承诺过多。如果将一个子类的引用赋给一个超类变量,编译器是允许的。但将一个超类的引用赋给一个子类变量时,就承诺过多了。必须进行强制类型转换,这样才能够通过运行时的检査。

如果试图在继承链上进行向下的强制类型转换,并且 “谎报” 对象包含的内容,会发生什么情况呢?
Manager boss = (Manager) staff[1] ; // Error
运行这个程序时,Java 运行时系统将注意到你的承诺不符,并产生一个 ClassCastException 异常。如果没有捕获这个异常,那么程序就会终止。因此,应该养成这样一个良好的程序设计习惯:在进行类型转换之前,先查看是否能够成功地转换。为此只需要使用 instanceof 操作符就可以实现。例如:

if(staff[1] instanceof Manager) {
    boss = (Manager) staff[1];
    ...
}

最后,如果这个类型转换不可能成功,编译器就不会让你完成这个转换。例如,下面这个强制类型转换:
String c = (String) staff[1];
将会产生编译错误,这是因为 String 不是 Employee 的子类。

强制类型转换注意事项:

  • 只能在继承层次内进行强制类型转换。
  • 在将超类强制转换成子类之前,应该使用 instanceof 进行检查。

如果 x 为 null,进行以下测试
x instanceof C
不会产生异常,只是返回 false。之所以这样处理是因为 null 没有引用任何对象,当然也不会引用 C 类型的对象。

实际上,通过强制类型转换来转换对象的类型通常并不是一种好的做法。在我们的示例中,大多数情况并不需要将 Employee 对象强制转换成 Manager 对象,两个类的对象都能够正确地调用 getSalary 方法,这是因为实现多态性的动态绑定机制能够自动地找到正确的方法。

只有在使用 Manager 中特有的方法时才需要进行类型转换。如果出于某种原因发现需要在 Employee 对象上调用 Manager 中特有的 setBonus 方法,那么就应该自问超类的设计是否合理。可能需要重新设计超类,并添加 setBonus 方法,这才是更合适的选择。请记住,只要没有捕获 ClassCastException 异常,程序就会终止执行。 一般情况下,最好尽量少用强制类型转换和 instanceof 运算符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值