java的引用类型转换分为两种:java
现存在一个Animal动物类,猫子类和狗子类继承于Animal父类;数组
1 public class Animal { 2 private String name; 3 4 public String getName() { 5 return name; 6 } 7 8 public void setName(String name) { 9 this.name = name; 10 } 11 12 public void eat() { 13 14 } 15 } 16 17 public class Cat extends Animal { 18 public void eatFish() { 19 System.out.println("猫吃鱼"); 20 } 21 } 22 23 public class Dog extends Animal { 24 public void eatBone() { 25 System.out.println("狗吃骨头"); 26 } 27 }
实例化一个cat对象,以下:优化
1 Cat cat1 = new Cat(); //使用子类引用实例化子类对象 2 3 Animal cat2 = cat1; 4 //此时为向上引用转换,小类型转换为大类型,并无风险 5 6 //Cat cat3 = cat2; //报错 7 //因为cat2已是Animal类的引用,因此此时为向下引用转换,即大类型转换为小类型,有数据溢出的风险 8 //虽然有风险,但也能够强制转换 9 Cat cat3 = (Cat)cat2; //强制转换成功 10 11 //Dog dog1 = cat2; //由于子类不一样因此不能这样引用 12 //Dog dog1 = (Dog)cat2; //即便强制转换也不行
虽然向下引用转换会存在风险,可是能够利用java的instanceof关键字去解决这个问题。instanceof运算符用法:判断是一个实例对象是否属于一个类,是返回true,不然返回false。这样咱们能够优化上面的代码避免强制转换类型时出现的问题:this
1 /** 2 * instanceof运算符用法 3 * 运算符是双目运算符,左面的操做元是一个对象,右面是一个类.当 4 * 左面的对象是右面的类建立的对象时,该运算符运算的结果是true,不然是false 5 * 6 * 说明:(1)一个类的实例包括自己的实例,以及全部直接或间接子类的实例 7 * (2)instanceof左边操做元显式声明的类型与右边操做元必须是同种类或右边是左边父类的继承关系, 8 * (3)不一样的继承关系下,编译出错 9 */ 10 if(cat2 instanceof Dog) { 11 Dog dog = (Dog)cat2; 12 }else { 13 System.out.println("并不能转换"); 14 }
可是当子类实例对象统一放进父类引用对象数组时,若要使用子类中的方法,必须先向下转换类型为子类引用,否则编译器会报错spa
1 Animal[] animals = { 2 new Cat(), 3 new Dog() 4 }; 5 6 7 //animals[1].eatFish(); //报错 8 if(animals[1] instanceof Cat) { 9 Cat cat = (Cat)animals[1]; 10 }