Проверить тип примитивного поля

Я пытаюсь определить тип поля объекта. Я не знаю тип объекта, когда он передается мне, но мне нужно найти поля, которые равны longs. Достаточно легко отличить коробочные Long, но примитивные long кажутся более сложными.

Я могу убедиться, что передаваемые мне объекты имеют только Longs, а не примитивы, но я бы этого не хотел. Итак, что у меня есть:

for (Field f : o.getClass().getDeclaredFields()) {
    Class<?> clazz = f.getType();
    if (clazz.equals(Long.class)) {
        // found one -- I don't get here for primitive longs
    }
}

Хакерский способ, который, кажется, работает, таков:

for (Field f : o.getClass().getDeclaredFields()) {
    Class<?> clazz = f.getType();
    if (clazz.equals(Long.class) ||  clazz.getName().equals("long")) {
        // found one
    }
}

Мне бы очень хотелось более чистый способ сделать это, если он есть. Если нет лучшего способа, то я думаю, что требование, чтобы объекты, которые я получаю, использовали только Long (не long), было бы лучшим API.

Любые идеи?


person macbutch    schedule 11.12.2009    source источник


Ответы (4)


Вы используете неправильную константу для проверки примитивов Long - используйте Long.TYPE, каждый другой тип примитива можно найти с аналогично названной константой в оболочке. например: Byte.TYPE, Character.TYPE и т. д.

person mP.    schedule 11.12.2009

Вы можете просто использовать

boolean.class
byte.class
char.class
short.class
int.class
long.class
float.class
double.class
void.class

Если вы используете отражение, то какое вам дело, зачем вообще делать эту проверку. Методы get/set всегда используют объекты, поэтому вам не нужно знать, является ли поле примитивным типом (если вы не пытаетесь установить для примитивного типа нулевое значение).

На самом деле, для метода get() вам не нужно знать, к какому типу он относится. Ты можешь сделать

// any number type is fine.
Number n = field.get(object);
long l = n.longValue();

Если вы не уверены, что это числовой тип, вы можете сделать

Object o = field.get(object); // will always be an Object or null.
if (o instanceof Number) {
     Number n = (Number) o;
     long l = n.longValue();
person Peter Lawrey    schedule 12.12.2009
comment
Спасибо, я тоже не знал о long.class. У меня нет времени проверять это, но я не думаю, что остальная часть вашего комментария применима в моем конкретном случае (поправьте меня, если я ошибаюсь. Если я сделаю это: Class‹?› returnType = m.getReturnType() ; if (returnType.equals(Long.class)) { // делаем что-то } Я не думаю, что это сработает - мне все равно нужно проверить long.class или Long.TYPE. Если бы я мог просто вызвать все get ...(), тогда я мог бы просто проверить, что возвращается (но я не могу этого сделать). Пожалуйста, дайте мне знать, если я неправильно понял (вероятно...). - person macbutch; 16.12.2009
comment
Я надеюсь, вы можете прочитать это... Я забыл, что форматирование не выйдет. :( - person macbutch; 16.12.2009
comment
пытаться; если (returnType == Long.class || returnType == long.class) - person Peter Lawrey; 16.12.2009
comment
Приведение всех числовых типов к long отличается от извлечения только longs - person jpaugh; 22.01.2016
comment
Как вы проверяете, что у вас есть числовой тип? field.getType().isPrimitive() не работает, потому что это верно как для booleans, так и для чисел. - person jpaugh; 22.01.2016
comment
@jpaugh, считаете ли вы char числовым типом? Самое простое решение — иметь набор классов, которые вы считаете числовым типом. - person Peter Lawrey; 22.01.2016
comment
Правильно ли longValue принуждает char к long? Если да, то да. Если нет, то нет. Я хотел сказать, что опубликованный вами сокращенный код не обрабатывает все случаи; он делает предположение о возможных типах поля, с которым вы работаете. Это отвечает на вопрос, но было бы лучше более общее решение, особенно для задачи метапрограммирования. - person jpaugh; 22.01.2016
comment
Конечно, прошло 7 лет, так что ценность его замены, я полагаю, уменьшилась. - person jpaugh; 22.01.2016
comment
@jpaugh Я прочитал это как проверку определенного примитивного типа. В OP не упоминается проверка числового типа. - person Peter Lawrey; 22.01.2016
comment
Как и я. И я прочитал ваш пост как дающий два отдельных ответа: первый (в основном) на английском, а второй (в основном) в коде. Нижний на самом деле не проверяет, соответствует ли тип конкретному типу, который нужен OP. Если этого не произойдет, он потерпит неудачу. (Я предполагаю, что OP не знает заранее, какие поля имеют необходимый тип.) - person jpaugh; 22.01.2016
comment
@jpaugh Я пояснил, что означает любой числовой тип. - person Peter Lawrey; 22.01.2016
comment
Спасибо, что развлекли мою придирку! - person jpaugh; 22.01.2016

  • Чтобы обнаружить поля с типом long, используйте long.class или Long.TYPE.

  • Для обнаружения полей с типом Long используйте Long.class.

Пример:

for (Field f : o.getClass().getDeclaredFields()) {
    Class<?> clazz = f.getType();
    // to detect both Long and long types
    if (Long.class.equals(clazz) || long.class.equals(clazz)) {
        // found one
    }
}

Примечание:

Long.TYPE является статическим константным членом и эквивалентен long.class.

фрагмент кода формы Long Класс

/**
 * The {@link Class} object that represents the primitive type {@code long}.
 */
@SuppressWarnings("unchecked")
public static final Class<Long> TYPE
        = (Class<Long>) long[].class.getComponentType();

Также проверьте ответ для Разница между Integer.class и Integer.TYPE вопрос

person ahmed hamdy    schedule 07.09.2016

person    schedule
comment
Да, я посмотрел на это, но мне нужно знать, является ли это длинным примитивом, а не просто примитивом. т. е. соответствуют всем длинным примитивам, но не целым числам или байтам и т. д. - person macbutch; 16.12.2009