美文网首页
Java反射(4)Array

Java反射(4)Array

作者: juconcurrent | 来源:发表于2020-04-09 22:51 被阅读0次

    为什么需要用到Array

    我们知道,所有的类最终都是继承于Object。我们可以将子类赋值给父类,但是却不能将父类赋值给子类。同样的,对于数组来说,我们可以将子类数组赋值给父类数组,却不能将父类数组赋值给子类,这样会抛出异常java.lang.ClassCastException

    下面代码就没有任何问题,可以编译,也可以允许。

    String[] strings1 = new String[5];
    Object[] objects1 = strings1;
    

    而下面的代码却会出现强转异常。

    Object[] objects2 = new Object[5];
    String[] strings2 = (String[])objects2;
    

    将会在运行时出现以下错误。

    java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
    

    Array

    该类的完整类路径为java.lang.reflect.Array,其所有方法皆为静态方法。其常用方法如下:

    // 以特定类型,构建指定长度的一维数组
    public static Object newInstance(Class<?> componentType, int length);
    
    // 以特定类型,构建指定维度、指定长度的多维数组
    public static Object newInstance(Class<?> componentType, int... dimensions);
    
    // 获取数组的长度
    public static native int getLength(Object array);
    
    // 获取数组指定下标的值
    public static native Object get(Object array, int index);
    
    // 获取数组指定下标的值(主要为基本数组类型)
    public static native boolean getBoolean(Object array, int index);
    public static native byte getByte(Object array, int index);
    public static native char getChar(Object array, int index);
    // ...
    
    // 在数组的指定下标位置设置值
    public static native void set(Object array, int index, Object value)
    
    // 在数组的指定下标位置设置值(主要用于设置基本类型数组的值)
    public static native void setBoolean(Object array, int index, boolean z);
    public static native void setByte(Object array, int index, byte b);
    public static native void setChar(Object array, int index, char c);
    // ...
    

    Arrays

    Array用于通过反射操作数组,而Arrays则是通过一系列的方法来操作数组。其完成类路径为java.util.Arrays。例如:

    • 串行排序
    • 并行排序
    • 二分查找
    • 填充数值
    • 数组拷贝
    • 转换list
    • 流式计算
    • 深拷贝和深hash

    这些操作更多的是以静态方法的方式提供。而这些方法中,和Array关联比较大的在于数组拷贝。我们来看看:

    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
    
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
    

    最终调用了下面的方法,这个方法做了几件事情:

    1. 判断拷贝后的类型和拷贝前的类型是否都是Object数组?
    2. 如果是,则创建指定长度的Object数组
    3. 如果不是,则通过Array的创建数组静态方法,创建指定类型、指定长度的数组
    4. 将原始数组的元素依次拷贝到新数组

    例子

    public static void main(String[] args) {
        Object array = Array.newInstance(int.class, 5);
        Array.set(array, 0, 99);
        Array.set(array, 1, 98);
        Array.set(array, 2, 97);
        Array.set(array, 3, 96);
        Array.set(array, 4, 95);
    
        System.out.println(Array.get(array, 0));
        System.out.println(Array.get(array, 1));
        System.out.println(Array.get(array, 2));
        System.out.println(Array.get(array, 3));
        System.out.println(Array.get(array, 4));
    }
    

    输出结果如下:

    99
    98
    97
    96
    95
    

    参考文档

    相关文章

      网友评论

          本文标题:Java反射(4)Array

          本文链接:https://www.haomeiwen.com/subject/hpjkmhtx.html