确定一个对象是否是原始类型

时间:2023-01-16 16:30:16

I have an Object[] array, and I am trying to find the ones that are primitives. I've tried to use Class.isPrimitive(), but it seems I'm doing something wrong:

我有一个对象[]数组,我试图找到那些原语。我试着使用Class.isPrimitive(),但好像我做错了什么:

int i = 3;
Object o = i;

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

prints java.lang.Integer, false.

打印. lang。整数,假的。

Is there a right way or some alternative?

是否有正确的方法或选择?

17 个解决方案

#1


143  

The types in an Object[] will never really be primitive - because you've got references! Here the type of i is int whereas the type of the object referenced by o is Integer (due to auto-boxing).

对象[]中的类型永远不会是原始类型——因为您有引用!这里我的类型是int型的,而o所引用的对象的类型是整数(由于自动装箱)。

It sounds like you need to find out whether the type is "wrapper for primitive". I don't think there's anything built into the standard libraries for this, but it's easy to code up:

听起来您需要查明类型是否为“原语包装器”。我认为标准库中并没有为此构建任何东西,但是很容易编写代码:

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;
    }
}

#2


70  

commons-lang ClassUtils has relevant methods. The new version has:

common -lang ClassUtils有相关的方法。新版本有:

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

The old versions have wrapperToPrimitive(clazz) method, which will return the primitive correspondence. So you can do:

旧版本有wrapperToPrimitive(clazz)方法,它将返回原始通信。所以你能做什么:

boolean isPrimitiveOrWrapped = 
    clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;

#3


23  

Google's Guava library has a Primitives utility that check if a class is a wrapper type for a primitive: http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/primitives/Primitives.html

谷歌的Guava库有一个原语实用程序,用于检查类是否是原语的包装器类型:http://guava- libraries.googlecode.com/svn/trunk/trunk/javadoc/com/google/common/common/basitives/basic .html

Primitives.isWrapperType(class)

Class.isPrimitive() works for primitives

适用于原语Class.isPrimitive()

#4


15  

For those who like terse code.

对于那些喜欢简洁代码的人。

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);
}

#5


8  

Starting in Java 1.5 and up, there is a new feature called auto-boxing. The compiler does this itself. When it sees an opportunity, it converts a primitive type into its appropriate wrapper class.

从Java 1.5开始,有一个新特性叫做自动装箱。编译器自己做这个。当它看到机会时,它会将原始类型转换为适当的包装类。

What is probably happening here is when you declare

你申报的时候可能发生了什么

Object o = i;

The compiler will compile this statement as saying

编译器将编译这个语句。

Object o = Integer.valueOf(i);

This is auto-boxing. This would explain the output you are receiving. This page from the Java 1.5 spec explains auto-boxing more in detail.

这是auto-boxing。这将解释您正在接收的输出。这个来自Java 1.5规范的页面更详细地解释了自动装箱。

#6


6  

Integer is not a primitive, Class.isPrimitive() is not lying.

Integer不是原语,Class.isPrimitive()不是撒谎。

#7


5  

You have to deal with the auto-boxing of java.
Let's take the code

您必须处理java的自动装箱。让我们的代码

public class test
{
    public static void main(String [ ] args)
    {
        int i = 3;
        Object o = i;
        return;
    }
}
You get the class test.class and javap -c test let's you inspect the generated bytecode.
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

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

公共静态void main(以[]);

}

}

As you can see the java compiler added
invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
to create a new Integer from your int and then stores that new Object in o via astore_2

#8


4  

I think this happens due to auto-boxing.

我想这是因为自动装箱。

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

You may implement a utility method that matches these specific boxing classes and gives you if a certain class is primitive.

您可以实现与这些特定的装箱类相匹配的实用工具方法,并在某个类是原语的情况下为您提供。

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);
}

#9


3  

Just so you can see that is is possible for isPrimitive to return true (since you have enough answers showing you why it is false):

你可以看到isPrimitive返回true是可能的(因为你有足够的答案来说明为什么它是假的):

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

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

This matters in reflection when a method takes in "int" rather than an "Integer".

当方法采用“int”而不是“Integer”时,这一点在反射中很重要。

This code works:

这段代码:

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)
    {
    }
}

This code fails (cannot find the method):

此代码失败(找不到方法):

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)
    {
    }
}

#10


2  

As several people have already said, this is due to autoboxing.

正如一些人已经说过的,这是由于自动装箱。

You could create a utility method to check whether the object's class is Integer, Double, etc. But there is no way to know whether an object was created by autoboxing a primitive; once it's boxed, it looks just like an object created explicitly.

您可以创建一个实用工具方法来检查对象的类是否为整数、双精度等。但是无法知道一个对象是否由自动装箱原语创建;一旦被装箱,它看起来就像一个显式创建的对象。

So unless you know for sure that your array will never contain a wrapper class without autoboxing, there is no real solution.

因此,除非您确信您的数组中不会包含没有自动装箱的包装类,否则就没有真正的解决方案。

#11


2  

The primitve wrapper types will not respond to this value. This is for class representation of primitives, though aside from reflection I can't think of too many uses for it offhand. So, for example

primitve包装器类型不会响应这个值。这是对原语的类表示,尽管除了反射之外,我不能马上想到它有太多的用途。所以,举个例子

System.out.println(Integer.class.isPrimitive());

prints "false", but

打印“false”,但是

public static void main (String args[]) throws Exception
{
    Method m = Junk.class.getMethod( "a",null);
    System.out.println( m.getReturnType().isPrimitive());
}

public static int a()
{
    return 1;
}

prints "true"

打印“true”

#12


1  

This is the simplest way I could think of. The wrapper classes are present only in java.lang package. And apart from the wrapper classes, no other class in java.lang has field named TYPE. You could use that to check whether a class is Wrapper class or not.

这是我能想到的最简单的方法。包装类只存在于java中。朗包。除了包装类,java中没有其他类。lang有字段命名为TYPE。您可以使用它来检查类是否是包装类。

public static boolean isBoxingClass(Class<?> clazz)
{
    String pack = clazz.getPackage().getName();
    if(!"java.lang".equals(pack)) 
        return false;
    try 
    {
        clazz.getField("TYPE");
    } 
    catch (NoSuchFieldException e) 
    {
        return false;
    }           
    return true;        
}

#13


1  

Get ahold of BeanUtils from Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/

从Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/获取BeanUtils

Probably the Apache variation (commons beans) has similar functionality.

可能Apache变体(commons bean)具有类似的功能。

#14


1  

I'm late to the show, but if you're testing a field, you can use getGenericType:

我来晚了,但是如果你在测试一个字段,你可以使用getGenericType:

import static org.junit.Assert.*;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;

import org.junit.Test;

public class PrimitiveVsObjectTest {

    private static final Collection<String> PRIMITIVE_TYPES = 
            new HashSet<>(Arrays.asList("byte", "short", "int", "long", "float", "double", "boolean", "char"));

    private static boolean isPrimitive(Type type) {
        return PRIMITIVE_TYPES.contains(type.getTypeName());
    }

    public int i1 = 34;
    public Integer i2 = 34;

    @Test
    public void primitive_type() throws NoSuchFieldException, SecurityException {
        Field i1Field = PrimitiveVsObjectTest.class.getField("i1");
        Type genericType1 = i1Field.getGenericType();
        assertEquals("int", genericType1.getTypeName());
        assertNotEquals("java.lang.Integer", genericType1.getTypeName());
        assertTrue(isPrimitive(genericType1));
    }

    @Test
    public void object_type() throws NoSuchFieldException, SecurityException {
        Field i2Field = PrimitiveVsObjectTest.class.getField("i2");
        Type genericType2 = i2Field.getGenericType();
        assertEquals("java.lang.Integer", genericType2.getTypeName());
        assertNotEquals("int", genericType2.getTypeName());
        assertFalse(isPrimitive(genericType2));
    }
}

The Oracle docs list the 8 primitive types.

Oracle文档列出了8种基本类型。

#15


1  

you could determine if an object is wrapper type by beneath statements:

您可以通过下面的语句确定一个对象是否是包装器类型:

***objClass.isAssignableFrom(Number.class);***

and you could also determine a primitive object by using the isPrimitive() method

您还可以使用isPrimitive()方法来确定一个原始对象

#16


1  

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;
}

#17


0  

public class CheckPrimitve {
    public static void main(String[] args) {
        int i = 3;
        Object o = i;
        System.out.println(o.getClass().getSimpleName().equals("Integer"));
        Field[] fields = o.getClass().getFields();
        for(Field field:fields) {
            System.out.println(field.getType());
        }
    }
}  

Output:
true
int
int
class java.lang.Class
int

#1


143  

The types in an Object[] will never really be primitive - because you've got references! Here the type of i is int whereas the type of the object referenced by o is Integer (due to auto-boxing).

对象[]中的类型永远不会是原始类型——因为您有引用!这里我的类型是int型的,而o所引用的对象的类型是整数(由于自动装箱)。

It sounds like you need to find out whether the type is "wrapper for primitive". I don't think there's anything built into the standard libraries for this, but it's easy to code up:

听起来您需要查明类型是否为“原语包装器”。我认为标准库中并没有为此构建任何东西,但是很容易编写代码:

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;
    }
}

#2


70  

commons-lang ClassUtils has relevant methods. The new version has:

common -lang ClassUtils有相关的方法。新版本有:

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

The old versions have wrapperToPrimitive(clazz) method, which will return the primitive correspondence. So you can do:

旧版本有wrapperToPrimitive(clazz)方法,它将返回原始通信。所以你能做什么:

boolean isPrimitiveOrWrapped = 
    clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;

#3


23  

Google's Guava library has a Primitives utility that check if a class is a wrapper type for a primitive: http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/primitives/Primitives.html

谷歌的Guava库有一个原语实用程序,用于检查类是否是原语的包装器类型:http://guava- libraries.googlecode.com/svn/trunk/trunk/javadoc/com/google/common/common/basitives/basic .html

Primitives.isWrapperType(class)

Class.isPrimitive() works for primitives

适用于原语Class.isPrimitive()

#4


15  

For those who like terse code.

对于那些喜欢简洁代码的人。

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);
}

#5


8  

Starting in Java 1.5 and up, there is a new feature called auto-boxing. The compiler does this itself. When it sees an opportunity, it converts a primitive type into its appropriate wrapper class.

从Java 1.5开始,有一个新特性叫做自动装箱。编译器自己做这个。当它看到机会时,它会将原始类型转换为适当的包装类。

What is probably happening here is when you declare

你申报的时候可能发生了什么

Object o = i;

The compiler will compile this statement as saying

编译器将编译这个语句。

Object o = Integer.valueOf(i);

This is auto-boxing. This would explain the output you are receiving. This page from the Java 1.5 spec explains auto-boxing more in detail.

这是auto-boxing。这将解释您正在接收的输出。这个来自Java 1.5规范的页面更详细地解释了自动装箱。

#6


6  

Integer is not a primitive, Class.isPrimitive() is not lying.

Integer不是原语,Class.isPrimitive()不是撒谎。

#7


5  

You have to deal with the auto-boxing of java.
Let's take the code

您必须处理java的自动装箱。让我们的代码

public class test
{
    public static void main(String [ ] args)
    {
        int i = 3;
        Object o = i;
        return;
    }
}
You get the class test.class and javap -c test let's you inspect the generated bytecode.
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

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

公共静态void main(以[]);

}

}

As you can see the java compiler added
invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
to create a new Integer from your int and then stores that new Object in o via astore_2

#8


4  

I think this happens due to auto-boxing.

我想这是因为自动装箱。

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

You may implement a utility method that matches these specific boxing classes and gives you if a certain class is primitive.

您可以实现与这些特定的装箱类相匹配的实用工具方法,并在某个类是原语的情况下为您提供。

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);
}

#9


3  

Just so you can see that is is possible for isPrimitive to return true (since you have enough answers showing you why it is false):

你可以看到isPrimitive返回true是可能的(因为你有足够的答案来说明为什么它是假的):

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

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

This matters in reflection when a method takes in "int" rather than an "Integer".

当方法采用“int”而不是“Integer”时,这一点在反射中很重要。

This code works:

这段代码:

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)
    {
    }
}

This code fails (cannot find the method):

此代码失败(找不到方法):

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)
    {
    }
}

#10


2  

As several people have already said, this is due to autoboxing.

正如一些人已经说过的,这是由于自动装箱。

You could create a utility method to check whether the object's class is Integer, Double, etc. But there is no way to know whether an object was created by autoboxing a primitive; once it's boxed, it looks just like an object created explicitly.

您可以创建一个实用工具方法来检查对象的类是否为整数、双精度等。但是无法知道一个对象是否由自动装箱原语创建;一旦被装箱,它看起来就像一个显式创建的对象。

So unless you know for sure that your array will never contain a wrapper class without autoboxing, there is no real solution.

因此,除非您确信您的数组中不会包含没有自动装箱的包装类,否则就没有真正的解决方案。

#11


2  

The primitve wrapper types will not respond to this value. This is for class representation of primitives, though aside from reflection I can't think of too many uses for it offhand. So, for example

primitve包装器类型不会响应这个值。这是对原语的类表示,尽管除了反射之外,我不能马上想到它有太多的用途。所以,举个例子

System.out.println(Integer.class.isPrimitive());

prints "false", but

打印“false”,但是

public static void main (String args[]) throws Exception
{
    Method m = Junk.class.getMethod( "a",null);
    System.out.println( m.getReturnType().isPrimitive());
}

public static int a()
{
    return 1;
}

prints "true"

打印“true”

#12


1  

This is the simplest way I could think of. The wrapper classes are present only in java.lang package. And apart from the wrapper classes, no other class in java.lang has field named TYPE. You could use that to check whether a class is Wrapper class or not.

这是我能想到的最简单的方法。包装类只存在于java中。朗包。除了包装类,java中没有其他类。lang有字段命名为TYPE。您可以使用它来检查类是否是包装类。

public static boolean isBoxingClass(Class<?> clazz)
{
    String pack = clazz.getPackage().getName();
    if(!"java.lang".equals(pack)) 
        return false;
    try 
    {
        clazz.getField("TYPE");
    } 
    catch (NoSuchFieldException e) 
    {
        return false;
    }           
    return true;        
}

#13


1  

Get ahold of BeanUtils from Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/

从Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/获取BeanUtils

Probably the Apache variation (commons beans) has similar functionality.

可能Apache变体(commons bean)具有类似的功能。

#14


1  

I'm late to the show, but if you're testing a field, you can use getGenericType:

我来晚了,但是如果你在测试一个字段,你可以使用getGenericType:

import static org.junit.Assert.*;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;

import org.junit.Test;

public class PrimitiveVsObjectTest {

    private static final Collection<String> PRIMITIVE_TYPES = 
            new HashSet<>(Arrays.asList("byte", "short", "int", "long", "float", "double", "boolean", "char"));

    private static boolean isPrimitive(Type type) {
        return PRIMITIVE_TYPES.contains(type.getTypeName());
    }

    public int i1 = 34;
    public Integer i2 = 34;

    @Test
    public void primitive_type() throws NoSuchFieldException, SecurityException {
        Field i1Field = PrimitiveVsObjectTest.class.getField("i1");
        Type genericType1 = i1Field.getGenericType();
        assertEquals("int", genericType1.getTypeName());
        assertNotEquals("java.lang.Integer", genericType1.getTypeName());
        assertTrue(isPrimitive(genericType1));
    }

    @Test
    public void object_type() throws NoSuchFieldException, SecurityException {
        Field i2Field = PrimitiveVsObjectTest.class.getField("i2");
        Type genericType2 = i2Field.getGenericType();
        assertEquals("java.lang.Integer", genericType2.getTypeName());
        assertNotEquals("int", genericType2.getTypeName());
        assertFalse(isPrimitive(genericType2));
    }
}

The Oracle docs list the 8 primitive types.

Oracle文档列出了8种基本类型。

#15


1  

you could determine if an object is wrapper type by beneath statements:

您可以通过下面的语句确定一个对象是否是包装器类型:

***objClass.isAssignableFrom(Number.class);***

and you could also determine a primitive object by using the isPrimitive() method

您还可以使用isPrimitive()方法来确定一个原始对象

#16


1  

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;
}

#17


0  

public class CheckPrimitve {
    public static void main(String[] args) {
        int i = 3;
        Object o = i;
        System.out.println(o.getClass().getSimpleName().equals("Integer"));
        Field[] fields = o.getClass().getFields();
        for(Field field:fields) {
            System.out.println(field.getType());
        }
    }
}  

Output:
true
int
int
class java.lang.Class
int