Java的反射机制

为了在Java中对问题部分进行处理,我使用了反射API,并使用Class来获取类型信息。因为Class甚至可以处理原始类型,所以我经常使用Class,但现在我找到了反射的情况,所以只需要与以前的模式配合简单地进行备忘。

在使用反射时,有一些常见的类、字段、方法等选项,那么对于其他情况应该如何处理呢?

在传递参数的情况下是否用于判断的方法?

基本类型

在Java中,像int、long和double这样的基本数据类型并不是Class,但是它们都有对应的Class,在其中定义了Integer.TYPE等TYPE的常量。通过细致地比较这些类型信息,我们可以知道它们是哪一种类型。

可以通过获取类并使用Class#isPrimitive()方法来判断是原始类型还是对象。

数组

因为数组可以作为对象来处理,所以可以通过获取类 (Class) 来进行操作,并且可以通过 Class#isArray() 方法来进行检查。可以使用 Class#getComponentType() 等方法来获取元素的类型。

如果接收到的是一个数组,并且已经声明为Object类型,那么可以使用Array类来操作其元素。可以通过Arrays.asList((Object[])src)来将其转换为List类型,这是一种常见的写法。

当你掌握到这个程度,基本上你就能够进行类似对象映射的操作了。

泛型

使用List等<>来表示的表达,由于运行时的对象是使用new ArrayList<>()这样创建的,所以没有类型信息。在尝试将各种内容放入这样的定义中时,我遇到了转换的困难,但是看来Field似乎作为成员变量的类型信息是持有的,因此可以从那里获取。

class A<T> {
 List<Integer> b = new ArrayList<T>();
}

由于无法获取类型为b的List,因此无法确定new ArrayList()的T等。这可能只对对象映射等方面有用,通常无需了解。

void example(Class<A> cls) {

    String name = "b" // 変数名

// private から取得できる。 super classのものは cls.getSuperclass() などで別途取得しないと取れない
    Field field = cls.getDeclaredField(name);

   または

// public なものを継承関係も含めて取得できる
    Field field = cls.getField(name);
 

    Type  type = field.getGenericType();
}

目前的新要素类型是一个称为Type的类型,其中包含了类型为cls的b的类型信息,并且它是Class的超类型。如果有泛型等附加元素,则会以Class以外的形式返回更多的信息。

如果使用了泛型,会返回有关 ParameterizedType 接口的信息。

ParameterizedType#getActualTypeArguments() 可以以一个数组的形式返回<>内的类型。这也是一个Type。如果类型是嵌套的,那么这里仍然是一个ParameterizedType,否则可以认为是一个Class。

使用ParameterizedType.getRawType()方法可以获取与传统的Class相同的Type。对于List,它将返回List的类型信息。

既然还可以使用List这样的表示法,那么在这种情况下会发生什么呢…

bannerAds