继承之后的使用注意事项_ArrayStoreException

今天在看Core In Java第五章节时,看到一个很感兴趣的知识点,如下: 

在Java中,子类数组的引用可以转换成超类数组的引用,而不需要采用强制转换。但是,在超类数组的引用添加超类类型引用对象之后,就会出错(ArrayStoreException)!代码如下: 

Java代码  收藏代码
  1. /** 
  2.  * 在第五章节继承中提到了一个很重要的概念 
  3.  *  
  4.  * 确切的讲是一个继承使用时的忌讳 
  5.  *  
  6.  * 使用子类类型定义一个数组,然后让一个父类类型数组引用,在父类数组中添加父类类型对象,将出错 
  7.  *  
  8.  * ArrayStoreException 
  9.  *  
  10.  * @author Administrator 
  11.  *  
  12.  */  
  13. public class ArrayStoreExceptionTest {  
  14.   
  15.     /** 
  16.      * 测试在继承中的注意事项及忌讳 
  17.      *  
  18.      * @param args 
  19.      */  
  20.     public static void main(String[] args) {  
  21.         Student[] students = new Student[10];  
  22.         Person[] persons = students;  
  23.         // 内部类的实例化过程  
  24.         Person p1 = new ArrayStoreExceptionTest().new Person(1001, "Jessica");  
  25.         persons[0] = p1;  
  26.         students[0].setScore(200.1);  
  27.     }  
  28.   
  29.     /** 
  30.      * Super class Person 
  31.      *  
  32.      * @author Administrator 
  33.      *  
  34.      */  
  35.     class Person {  
  36.         private int id;  
  37.   
  38.         private String name;  
  39.   
  40.         public int getId() {  
  41.             return id;  
  42.         }  
  43.   
  44.         public void setId(int id) {  
  45.             this.id = id;  
  46.         }  
  47.   
  48.         public String getName() {  
  49.             return name;  
  50.         }  
  51.   
  52.         public void setName(String name) {  
  53.             this.name = name;  
  54.         }  
  55.   
  56.         public Person(int id, String name) {  
  57.             super();  
  58.             this.id = id;  
  59.             this.name = name;  
  60.         }  
  61.   
  62.         public Person() {  
  63.             super();  
  64.         }  
  65.   
  66.     }  
  67.   
  68.     /** 
  69.      * Subclass Student 
  70.      *  
  71.      * @author Administrator 
  72.      *  
  73.      */  
  74.     class Student extends Person {  
  75.         private double score;  
  76.   
  77.         public Student(int id, String name, double score) {  
  78.             super(id, name);  
  79.             this.score = score;  
  80.         }  
  81.   
  82.         public double getScore() {  
  83.             return score;  
  84.         }  
  85.   
  86.         public void setScore(double score) {  
  87.             this.score = score;  
  88.         }  
  89.     }  
  90. }  



以上代码中,在main()方法中的代码可以正常编译通过,在运行时将抛出一个ArrayStoreException的运行时异常,原因是:由于persons超类数组对象的引用指向了students子类数组对象的引用,当为persons[0]添加父类对象引用时,将出现这样的情况:JVM会进行检查,由于引用的是子类数组类型对象引用,添加父类引用类型对象如果可以通过,在以下语句将出现更严重的异常! 

Java代码  收藏代码
  1. students[0].setScore(200.1);  
  2. //将会访问一个不存在的实例域,进而搅乱相邻存储空间的内容!  



所以,以上代码块执行之后,将抛出ArrayStoreException,这是一个运行时异常的子类异常!这是使用继承之后的一种忌讳!一定要注意避免! 

Java代码  收藏代码
  1. Exception in thread "main" java.lang.ArrayStoreException:  
  2.   
  3. com.harry.coreInJava.chap5.ArrayStoreExceptionTest$Person  
  4.   
  5. at com.harry.coreInJava.chap5.ArrayStoreExceptionTest.main  
  6.   
  7. (ArrayStoreExceptionTest.java:30)  




所以,如果定义的是一个数组类型对象,则有必要记住这个对象中可以添加什么类型的对象,而不是因为继承关系而扰乱了我们的判断力!

posted @ 2016-09-24 15:53  邱明成  阅读(375)  评论(0编辑  收藏  举报