Определение, является ли Объект примитивного типа - PullRequest
99 голосов
/ 02 апреля 2009

У меня есть массив Object[], и я пытаюсь найти те, которые являются примитивами. Я пытался использовать Class.isPrimitive(), но кажется, что я делаю что-то не так:

int i = 3;
Object o = i;

System.out.println(o.getClass().getName() + ", " +
                   o.getClass().isPrimitive());

отпечатков java.lang.Integer, false.

Есть ли верный путь или какая-то альтернатива?

Ответы [ 17 ]

155 голосов
/ 02 апреля 2009

Типы в Object[] никогда не будут действительно примитивными - потому что у вас есть ссылки! Здесь тип i равен int, тогда как тип объекта, на который ссылается o, равен Integer (из-за автобокса).

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

import java.util.*;

public class Test
{
    public static void main(String[] args)        
    {
        System.out.println(isWrapperType(String.class));
        System.out.println(isWrapperType(Integer.class));
    }

    private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();

    public static boolean isWrapperType(Class<?> clazz)
    {
        return WRAPPER_TYPES.contains(clazz);
    }

    private static Set<Class<?>> getWrapperTypes()
    {
        Set<Class<?>> ret = new HashSet<Class<?>>();
        ret.add(Boolean.class);
        ret.add(Character.class);
        ret.add(Byte.class);
        ret.add(Short.class);
        ret.add(Integer.class);
        ret.add(Long.class);
        ret.add(Float.class);
        ret.add(Double.class);
        ret.add(Void.class);
        return ret;
    }
}
72 голосов
/ 30 сентября 2010

commons-lang ClassUtils имеет соответствующие методы .

Новая версия имеет:

boolean isPrimitiveOrWrapped = 
    ClassUtils.isPrimitiveOrWrapper(object.getClass());

Старые версии имеют метод wrapperToPrimitive(clazz), который возвращает соответствие примитив .

boolean isPrimitiveOrWrapped = 
    clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
24 голосов
/ 31 января 2012

В библиотеке Google Guava есть утилита Primitives, которая проверяет, является ли класс типом оболочки для примитива: http://guava -libraries.googlecode.com / SVN / багажник / Javadoc / COM / Google / общие / примитивы / Primitives.html

Primitives.isWrapperType(class)

Class.isPrimitive () работает для примитивов

16 голосов
/ 02 апреля 2009

Для тех, кто любит краткий код.

private static final Set<Class> WRAPPER_TYPES = new HashSet(Arrays.asList(
    Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class));
public static boolean isWrapperType(Class clazz) {
    return WRAPPER_TYPES.contains(clazz);
}
8 голосов
/ 02 апреля 2009

Начиная с Java 1.5 и выше, появилась новая функция, называемая автобоксом. Компилятор делает это сам. Когда он видит возможность, он преобразует примитивный тип в соответствующий класс-оболочку.

Что, вероятно, происходит здесь, когда вы объявляете

Object o = i;

Компилятор скомпилирует это утверждение как "

Object o = Integer.valueOf(i);

Это автобокс. Это объяснит результат, который вы получаете. Эта страница из спецификации Java 1.5 объясняет автобокс более подробно.

6 голосов
/ 02 апреля 2009

Integer не примитив, Class.isPrimitive() не врет.

5 голосов
/ 21 сентября 2017
public static boolean isValidType(Class<?> retType)
{
    if (retType.isPrimitive() && retType != void.class) return true;
    if (Number.class.isAssignableFrom(retType)) return true;
    if (AbstractCode.class.isAssignableFrom(retType)) return true;
    if (Boolean.class == retType) return true;
    if (Character.class == retType) return true;
    if (String.class == retType) return true;
    if (Date.class.isAssignableFrom(retType)) return true;
    if (byte[].class.isAssignableFrom(retType)) return true;
    if (Enum.class.isAssignableFrom(retType)) return true;
    return false;
}
5 голосов
/ 02 апреля 2009

Думаю, это происходит из-за автобокса .

int i = 3;
Object o = i;
o.getClass().getName(); // prints Integer

Вы можете реализовать служебный метод, который соответствует этим конкретным классам бокса и дает вам, если определенный класс является примитивным.

public static boolean isWrapperType(Class<?> clazz) {
    return clazz.equals(Boolean.class) || 
        clazz.equals(Integer.class) ||
        clazz.equals(Character.class) ||
        clazz.equals(Byte.class) ||
        clazz.equals(Short.class) ||
        clazz.equals(Double.class) ||
        clazz.equals(Long.class) ||
        clazz.equals(Float.class);
}
5 голосов
/ 02 апреля 2009

Вы должны иметь дело с автобоксом Java.
Давайте возьмем код

public class test
{
    public static void main(String [ ] args)
    {
        int i = 3;
        Object o = i;
        return;
    }
}
. Вы получите класс test.class и javap -c test . Теперь давайте проверим сгенерированный байт-код.
Compiled from "test.java"
public class test extends java.lang.Object{
public test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return</p>

<p>public static void main(java.lang.String[]);
  Code:
   0:   iconst_3
   1:   istore_1
   2:   iload_1
   3:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   6:   astore_2
   7:   return</p>

<p>}
Как видно, добавлен компилятор java
invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
для создания нового Целое число из вашего int, а затем сохраняет этот новый объект в o через astore_2
3 голосов
/ 02 апреля 2009

Чтобы вы могли видеть, что isPrimitive может вернуть true (поскольку у вас достаточно ответов, показывающих, почему оно ложно):

public class Main
{
    public static void main(final String[] argv)
    {
        final Class clazz;

        clazz = int.class;
        System.out.println(clazz.isPrimitive());
    }
}

Это важно при отражении, когда метод принимает "int", а не "Integer".

Этот код работает:

import java.lang.reflect.Method;

public class Main
{
    public static void main(final String[] argv)
        throws Exception
    {
        final Method method;

        method = Main.class.getDeclaredMethod("foo", int.class);
    }

    public static void foo(final int x)
    {
    }
}

Этот код не работает (не удается найти метод):

import java.lang.reflect.Method;

public class Main
{
    public static void main(final String[] argv)
        throws Exception
    {
        final Method method;

        method = Main.class.getDeclaredMethod("foo", Integer.class);
    }

    public static void foo(final int x)
    {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...