Отражение Java & isInstance на примитивах - PullRequest
1 голос
/ 15 июня 2011

Я, должно быть, что-то здесь упускаю, но у меня, похоже, есть некоторые проблемы с базовыми размышлениями.Я думал, что из-за таких вещей, как бокс, я получу правду за каждый из двух отпечатков ниже.Вот простой основной класс:

package com.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestingReflection {

    public static void main(String[] args) throws SecurityException,
                                                  NoSuchMethodException,
                                                  IllegalArgumentException, 
                                                  IllegalAccessException,
                                                  InvocationTargetException 
    {
        final Class c = Reflection.class;
        Reflection p = new Reflection();
        p.setIntObj(new Integer(1));
        p.setIntPrim(1);
        for (Field field : c.getDeclaredFields()) {
            char first = Character.toUpperCase(field.getName().charAt(0));
            String capitalized = first + field.getName().substring(1);
            Method getField = 
                  c.getDeclaredMethod("get" + capitalized, new Class [] {});
            Class fieldClass = getField.getReturnType();
            Method setField = 
                  c.getDeclaredMethod("set" + capitalized,
                                      new Class [] { fieldClass });
            Object value = getField.invoke(p, new Object [] {});
            if (value != null) {
                System.out.println("Field Class: " 
                                    + fieldClass.getName() 
                                    + " instanceOf: " 
                                    + fieldClass.isInstance(value) 
                                    + " Value Class: " 
                                    + value.getClass().getName());
            }
        }
    }
}

Вот класс, с которым я его запускаю:

package com.reflection;

public class Reflection {

    private int intPrim;
    private Integer intObj;
    public int getIntPrim() { return intPrim; }
    public void setIntPrim(int intPrim) { this.intPrim = intPrim; }
    public Integer getIntObj() { return intObj; }
    public void setIntObj(Integer intObj) { this.intObj = intObj; }
}

Вот вывод, который я получаю:

Field Class: int instanceOf: false Value Class: java.lang.Integer
Field Class: java.lang.Integer instanceOf: true Value Class: java.lang.Integer

Есть ли другой метод, который я должен использовать, чтобы определить это?isAssignableFrom также возвращает false для примитива.

Ответы [ 3 ]

5 голосов
/ 15 июня 2011

Самый простой способ получить тип примитива для int - это int.class Вы также можете использовать Integer.TYPE, но я считаю, что это для обратной совместимости.

Документ Java Class.isIntanceof (Object) сообщает

Если этот объект Class представляет примитивный тип, этот метод возвращает false.

Возможно, это бесполезное определение, но так оно и работает. Я не нашел простого способа получить класс-оболочку для примитивного типа, поэтому я использую предопределенный HashMap (в нем 9 классов, включая void)

3 голосов
/ 15 июня 2011

Посмотрите на Integer.TYPE

1 голос
/ 16 августа 2011

Если исходить из ответа Питера, то причина, по которой Class.isInstance () не может сообщать о примитивных типах, заключается в том, что любой примитив, переданный в качестве аргумента, должен быть помещен в коробку, чтобы быть переданным как Object. По сути, это делает метод бесполезным для Class объектов, представляющих примитивные типы.

Конечно, в вашем случае значение int уже было упаковано с вашим вызовом:

Object value = getField.invoke(p, new Object [] {});
...