美文网首页
(8)关于数组反射的基本使用

(8)关于数组反射的基本使用

作者: Mrsunup | 来源:发表于2018-10-06 12:55 被阅读0次

    在写这一篇文章之前,关于数组的反射的操作有了解多少

    思考一下:
    如何知道一个对象为一个数组,如何获取数组中的单元的类型
    如何操作一个数组,对数组的下标进行反射设值

    带着这些问题,文章的讲解方面如下:

    鉴别数组类型
    用反射创建一个数组
    访问和设值数组元素
    数组的反射错误用法

    1.鉴别数组类型

    /**
     * 鉴别数组类型
     *    Class.isArray  可以判断类型是否为数组
     *    class.getComponentType 可以得到一个数组元素类型
     *   对于字段类型为:byte[],type为class [B  ,componmentType组件类型为byte
     *   对于字段类型为:String[][],type为 class [[Ljava.lang.String;   ,componmentType组件类型为一维数组 [Ljava.lang.String;
     */
    public class ArrayFind {
        public static void main(String... args) {
            args  =new String []{"java.nio.ByteBuffer"};
            boolean found = false;
            try {
                Class<?> cls = Class.forName(args[0]);
                Field[] flds = cls.getDeclaredFields();
                for (Field f : flds) {
                    //得到字段类型
                    Class<?> c = f.getType();
                    if (c.isArray()) {//判断类型是否是数组
                        found = true;
                        //c.getComponentType() 得到数组单元的类型
                        out.format("%s%n"
                                        + "           Field: %s%n"
                                        + "            Type: %s%n"
                                        + "  Component Type: %s%n",
                                f, f.getName(), c, c.getComponentType());
                    }
                }
                if (!found) {
                    out.format("No array fields%n");
                }
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            }
        }
    }
    

    输出 结果如下:

    final byte[] java.nio.ByteBuffer.hb
               Field: hb
                Type: class [B
      Component Type: byte
    

    2.用反射创建一个数组

    下面的例子展示了如何创建一个string数组,并给数组元素设置

    /**
     * @Project: jdk
     * @description:  数组的创建,以给数组设置值
     * @author: sunkang
     * @create: 2018-10-06 12:31
     * @ModificationHistory who      when       What
     **/
    public class ArrayStringCreator {
        public static void main(String[] args) {
            Class  clazz = String.class;
            //创建一个String 数组,长度为5
            Object arr =  Array.newInstance(clazz,5);
            //给数组指定的小标设置值
            Array.set(arr,0,"1");
            Array.set(arr,1,"2");
            Array.set(arr,2,"3");
            Array.set(arr,3,"4");
    
            //类型强转为String数组
            String[] oo  = (String[]) arr;
            System.out.println(Arrays.toString(oo));
        }
    }
    

    输出结果如下:

    [1, 2, 3, 4, null]
    

    3.访问和设值数组元素

    下面的例子展示了如何个二维数组的创建与设置值

    /**
     * 二维数组的创建与设值
     */
    public class CreateMatrix {
        public static void main(String... args) {
            //创建一个二维数组,相当于   new int[2][2];
            Object matrix = Array.newInstance(int.class, 2 ,2);
            //获取二维数组的第一行
            Object row0 = Array.get(matrix, 0);
            Object row1 = Array.get(matrix, 1);
            //二维数组设置值,第一行设置值
            Array.setInt(row0, 0, 1);
            Array.setInt(row0, 1, 2);
    
            //第二行设置值
            Array.setInt(row1, 0, 3);
            Array.setInt(row1, 1, 4);
    
            for (int i = 0; i < 2; i++)
                for (int j = 0; j < 2; j++)
                    out.format("matrix[%d][%d] = %d%n", i, j, ((int[][])matrix)[i][j]);
        }
    }
    

    结果为:

    matrix[0][0] = 1
    matrix[0][1] = 2
    matrix[1][0] = 3
    matrix[1][1] = 4
    

    4.数组的反射错误用法

    • 类型设置不正确
    /**
     * 数组类型设置不正确,导致 转换错误
     *原本类型是Integer数组,在发射代码中,类型检查只有在运行期间在会发生,所以无法对原生类型进行包装
     *  art[0] = 1   ,这个是可以的,因为编译器对1进行了包装,使1变成了引用类型
     */
    public class ArrayTroubleAgain {
        public static void main(String... args) {
            Integer[] ary = new Integer[2];
            try {
    //          Array.setInt(ary, 0, 1);  // IllegalArgumentException  不可以
    
    //          Array.setInt(ary,0,new Integer(1));//不可以
    
    
    //          Integer.isAssignableFrom().  符合这里对象是可以的
                //这里设置的1 当做是Ojbect对象
                Array.set(ary,0,1);  //可以,set用于引用类型
    
                Array.set(ary,0,new Integer(1));//可以
    
    
            } catch (IllegalArgumentException x) {
                err.format("Unable to box%n");
            } catch (ArrayIndexOutOfBoundsException x) {
                x.printStackTrace();
            }
        }
    }
    
    • 空数组引起的数组越界
    /**
     * 空数组的问题
     */
    public class ArrayTrouble {
        public static void main(String... args) {
            Object o = Array.newInstance(int.class, 0);
            int[] i = (int[])o;
            int[] j = new int[0];
            out.format("i.length = %d, j.length = %d, args.length = %d%n",
                       i.length, j.length, args.length);
            Array.getInt(o, 0);  // ArrayIndexOutOfBoundsException
        }
    }
    
    • 值缩小精度会出错
    /**
     * 
     * 值的精度缩小会出错的
     * 
     *  遵循的返回如下,这里 int数组,设置的元素必须是byte和short和int
     * byte , short, int, long, float, or double
     */
    public class ArrayTroubleToo {
        public static void main(String... args) {
            Object o = new int[2];
            Array.setByte(o,0,"2".getBytes()[0]);  //
            Array.setShort(o, 1, (short)2);  // widening, succeeds
    //        Array.setLong(o, 1, 2L);         // narrowing, fails   失去精度的操作将会出错
        }
    }
    

    相关文章

      网友评论

          本文标题:(8)关于数组反射的基本使用

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