*我是一个从汽车行业转行IT的项目经理,我是Edward。今天聊的是很容易弄混淆的一个基本语法,强制类型转换。
强制类型转换,能成功的条件只有如下两种情况:
-
引用所指向的对象,就是该类型
-
引用所指向的对象,实现了该接口或继承了该类
强转时若不符合如上两种情况,则发生ClassCastException类型转换异常
建议: 在强转之前先通过instanceof来判断引用指向的对象是否是该类型。
(P.S. 引用所指向的对象继承了该类这个场景比较少见,没有举例,不过可以联想一下三代继承的模型:爷爷代造型孙子类,孙子类强转成父类。)
强制类型转换最常用的场景:
向上构造后,想访问的那个方法在超类中没有的时候,需要强转
优点:
复用性好、扩展性好、维护性好
实例:
public class Test {
public static void main(String[] args) {
Bird[]birds=new Bird[5];
birds[0]=new Penguin();
birds[1]=new Penguin();
birds[2]=new Sparrow();
birds[3]=new Sparrow();
birds[4]=new Eagle();
for (int i = 0; i < birds.length; i++) {
if (birds[i] instanceof Penguin) {
Swim o1=(Swim)birds[i];
o1.swimming();
}
if (birds[i] instanceof Sparrow||birds[i] instanceof Eagle) {
Fly o2=(Fly)birds[i];
o2.flying();
}
}
}
}
public class Bird {
public void layegg() {
System.out.println("鸟会下蛋");
}
}
public interface Swim {
public abstract void swimming();
}
public interface Fly {
public abstract void flying();
}
public class Penguin extends Bird implements Swim{
@Override
public void swimming() {
System.out.println("企鹅会游泳");
}
}
public class Eagle extends Bird implements Fly{
@Override
public void flying() {
System.out.println("老鹰会飞");
}
}
public class Sparrow extends Bird implements Fly {
@Override
public void flying() {
System.out.println("麻雀会飞");
}
}
错误案例:
public class Cats {
public static void main(String args[]) {
// List<Cat> cats = new ArrayList<Cat>();
// cats.add(new Cat());
Animal b = new Animal();
Cat a = null;
if(b instanceof Animal)
a = (Cat)b; //weeklyExam.Animal and weeklyExam.Cat are in unnamed module of loader 'app'
//a = (Cat)b;处抛出java.lang.ClassCastException异常,b为Animal类型,并且具体引用对象是Animal对象,不能强转成Cat类型。
// if(a != null)
// cats.add(a);
// System.out.println(cats.size() +"cats");
}
}
class Animal {
}
class Cat extends Animal{
}
由于b为Animal类型,并且具体引用对象是Animal对象,Animal对象既不是该强转类型,也没有实现该接口或继承该类,故不能强转成Cat类型,抛出错误java.lang.ClassCastException异常,说明Animal and Cat are in unnamed module of loader ‘app’!