• Java中上转型对象数组


    先上结论:上转型对象数组,不能添加子类类型以外的元素,编译可以通过,但是运行时会报错。

    原文

    在Java中,Object[]数组可以是任何数组的父类(因为任何一个数组都可以向上转型为它在定义时指定元素类型的父类的数组)。

    考虑以下代码:

    String[] strs = new String[10];
    Object[] objs = strs;
    obj[0] = new Date(...);
    

    在上述代码中,我们将数组元素赋值为满足父类(Object)类型,但不同于原始类型(Pair)的对象,在编译时能够通过,而在运行时会抛出ArrayStoreException异常。

    测试

    当执行以下代码时:

            String[] strs=new String[10];
            Object[] objs=strs;
            objs[0]=new Date();
    

      确实报错:

    Exception in thread "main" java.lang.ArrayStoreException: java.util.Date
    	at com.czl.Mould.main(Mould.java:12)
    

      那看看上转型对象:

    System.out.println("上转型对象");
            String str=new String();
            Object obj=str;
            obj=new Date();
    

     编译通过,运行正常。这个很简单,obj指向的地址值被改变了而已。

    有意思了,看下面代码:

    class fa{
        fa(){
            System.out.println("fa construction");
            System.out.println("this"+this);
        }
    }
    
    class son extends fa{
        son(){
            System.out.println("son construction");
        }
    }
    
    class subson extends fa{
        subson(){System.out.println("subson construction");}
    }
    

     执行下面代码:

            fa[] fath = new son[10];
            fath[0]=new subson();
    

      结果报错:

    Exception in thread "main" java.lang.ArrayStoreException: com.czl.subson
    	at com.czl.Mould.main(Mould.java:15)
    fa construction
    thiscom.czl.subson@49e6f7cb
    subson construction
    

      

    执行下面代码:

    fa[] faths = new son[10];
    faths = new subson[10];
    faths[0] = new subson();
    System.out.println("faths[0]"+faths[0]);
    
    faths[1] = new son();
    System.out.println("faths[1]"+faths[1]);
    

      结果报错:

    fa construction
    thiscom.czl.subson@7e64eff0
    subson construction
    faths[0]com.czl.subson@7e64eff0
    fa construction
    thiscom.czl.son@20985fa2
    son construction
    Exception in thread "main" java.lang.ArrayStoreException: com.czl.son
    	at com.czl.Mould.main(Mould.java:21)
    

      

    拓展

    在泛型中,参数化类型的数组是不合法的。

    考虑以下代码:

    首先定义一个泛型类

    public class Pair<T, U> {
        private T first;
        private U second;
     
        public Pair(T first, U second) {
            this.first = first;
            this.second = second;
        }
     
        public T getFirst() {
            return first;
        }
     
        public U getSecond() {
            return second;
        }
     
        public void setFirst(T newValue) {
            first = newValue;
        }
     
        public void setSecond(U newValue) {
            second = newValue;
        }
    }
    

      基于以上原因,假设Java允许我们通过以下语句声明并初始化一个泛型数组:

    Pair<String, String>[] pairs = new Pair<String, String>[10];
    

      那么在虚拟机进行类型擦除后,实际上pairs成为了Pair[]数组,我们可以将它向上转型为Object[]数组。这时我们若往其中添加Pair<Date, Date>对象,便能通过编译时检查和运行时检查,而我们的本意是只想让这个数组存储Pair<String, String>对象,这会产生难以定位的错误。因此,Java不允许我们通过以上的语句形式声明并初始化一个泛型数组。

    可用如下语句声明并初始化一个泛型数组:

    Pair<String, String>[] pairs = (Pair<String, String>[]) new Pair[10];
    

      

  • 相关阅读:
    tsung基准测试方法、理解tsung.xml配置文件、tsung统计报告简介
    用指针方式,实现大小写字母户转,数字不变,遇到其他字符则停止转换并输出
    重写strcat函数,以实现strcat的功能
    重写strcpy函数,以实现strcpy的功能
    用指针的方式实现,重写strrchr函数的功能
    求指定整数范围内的素数之和
    求指定整数数组的中位数
    求一个数的阶乘
    LR中变量、参数的使用介绍
    Linux Shell流程例子
  • 原文地址:https://www.cnblogs.com/tooy/p/7461795.html
Copyright © 2020-2023  润新知