美文网首页
java 反射数组

java 反射数组

作者: hehehehe | 来源:发表于2020-11-18 07:57 被阅读0次

https://www.cnblogs.com/throwable/p/12272244.html

反射中可能用到的两个比较特殊的类型,数组和枚举,分别对应java.lang.reflect.Array和java.lang.Enum,后者其实并不是反射类库包中的类,但是反射的基础类库里面有使用枚举类型的方法

数组

数组是由Java虚拟机实现(这一点很重要,这就是为什么JDK类库中没有数组对应的类型的原因,array也不是Java中的保留关键字,操作数组的底层方法都是native方法),数组类型只有继承自java.lang.Object的方法,数组的length方法实际上并不属于数组类型的一部分,数组的length方法其实最终调用的是java.lang.reflect.Array#getLength(),注意到这个方法是native方法。java.lang.reflect.Array是基于反射操作数组的核心类。
使用反射方式就是使用java.lang.reflect.Array中的相关方法:
int[] arr = new int[10];

Class<?> c = Class.forName(cName);
Object o = Array.newInstance(c, n);
for (int i = 0; i < n; i++) {
    String v = cVals[i];
    Constructor ctor = c.getConstructor(String.class);
    Object val = ctor.newInstance(v);
    Array.set(o, i, val);
}
Object[] oo = (Object[]) o;

因为Java泛型擦除的问题,实际上我们使用Array#newInstance方法只能得到一个Object类型的结果实例,其实这个结果实例的类型就是ComponentType[],这里只是返回了它的父类(Object)类型实例,因此我们可以直接强转,例如:
String[] strArray = (String[]) Array.newInstance(String.class, 3);

反射条件下,可以通过Class.forName()获取数组类型,但是调用此方法的时候有个限制,类名必须使用JVM可以识别的签名形式,就是[L${ComponentType};,注意Class.forName()无法获取原始类型(如int、boolean)的类型

Double[] a=new Double[2];
System.out.println(a.getClass());
System.out.println(double[].class);
Class<?> aClass = Class.forName("[Ljava.lang.Double;");
System.out.println(aClass);

class [Ljava.lang.Double;
class [D
class [Ljava.lang.Double;

获取数组元素(组件)类型:Class#getComponentType()

枚举

所有枚举都继承自java.lang.Enum
boolean java.lang.Class#isEnum():判断类型是否枚举类型。
T[] java.lang.Class#getEnumConstants():获取类型中所有的枚举常量。
boolean java.lang.reflect.Field#isEnumConstant():判断属性是否枚举类型。

1、枚举类型会变成一个普通Java类,这个Java类会继承java.lang.Enum,并且把自身类型作为泛型参数类型,构造函数中必定包含name(字符串类型String)、ordinal(整型int)参数,因为父类java.lang.Enum的构造要求传入这两个参数。
2、所有的枚举成员属性都变成static final修饰的在第1步中提到的Java类的实例,属性的名称和原来枚举的名字一致,实例在静态代码块中创建。
3、新增了一个static final修饰的第1步中提到的Java类的数组实例,名称为$VALUES,此数组在静态代码块中创建,基于此数组还新增了一个静态方法values(),此方法就是直接返回数组的克隆。

public class EnumerationMain {

    enum Color {
        RED, BLACK, BLUE
    }

    public static class ColorHolder {

        private Color color = Color.BLACK;

    }

    public static void main(String[] args) throws Exception {
        Class<Color> colorClass = Color.class;
        System.out.println("Color class is enum:" + colorClass.isEnum());
        System.out.println("Color values:" + Arrays.toString(colorClass.getEnumConstants()));
        ColorHolder colorHolder = new ColorHolder();
        Class<ColorHolder> holderClass = ColorHolder.class;
        Field field = holderClass.getDeclaredField("color");
        field.setAccessible(true);
        System.out.println("Old color:" + field.get(colorHolder));
        field.set(colorHolder, Color.RED);
        System.out.println("New color:" + field.get(colorHolder));
    }
}

Color class is enum:true
Color values:[RED, BLACK, BLUE]
Old color:BLACK
New color:RED

相关文章

  • java 反射数组

    https://www.cnblogs.com/throwable/p/12272244.html[https:/...

  • Java数组的反射

    举个栗子来说明,写出通用的输出方法: 数组类型,将元素逐个输出 其他类型直接输出 注意:数组只有在元素类型相同、维...

  • 反射

    常用方法 反射得到数组 java.lang.Class类的getGenericInterfaces()方法用于获取...

  • 学习路线

    Java Se基础 Java基础语法、数组、类与对象、继承与多态、异常、范型、集合、流与文件、反射、枚举、自动装箱...

  • 博客地址

    java注解-01、java注解-02、Git面试资源java反射-01、java反射-02、java反射-03为...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Java基础之反射

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

网友评论

      本文标题:java 反射数组

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