美文网首页
(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)关于数组反射的基本使用

    在写这一篇文章之前,关于数组的反射的操作有了解多少 思考一下:如何知道一个对象为一个数组,如何获取数组中的单元的类...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 反射基本使用

    大家好,我是IT修真院上海分院第02期学员,一枚正直善良的java程序员。今天给分享一下关于Java反射的相关知识...

  • 反射的基本使用

    classFoo(object): def__init__(self,name,age): self.name =...

  • Swift基础-03(数组和字典)

    1.Swift中数组基本使用 数组的基本使用 `` 数组的遍历 数组的增删改 数组容量,这个在OC中我们经常使用在...

  • JNI--数组的访问

    今天来使用JNI对数组操作,数组分为基本类型数组和引用类型数组,首先来看下基本类型数组的使用 1.基本类型数组 我...

  • 关于反射的使用

    反射中获取泛型参数信息

  • 数组的基本使用

    var arr=[3,4,5,6] arr.length arr[0] arr[4]...undefined ar...

  • 数组的基本使用

    数组基本使用 当需要保存很多"相同类型"的数据的时候就可以使用数组来保存 数组的定义格式 元素类型 数组名称[元素...

  • 数组的基本使用

    push pop shift unshift join splice sort reverse concat

网友评论

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

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