Java 确定对象是否为原始类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/709961/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:36:52  来源:igfitidea点击:

Determining if an Object is of primitive type

javareflection

提问by drill3r

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:

我有一个Object[]数组,我试图找到那些是原语的。我试过使用Class.isPrimitive(),但似乎我做错了什么:

int i = 3;
Object o = i;

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

prints java.lang.Integer, false.

打印java.lang.Integer, false

Is there a right way or some alternative?

有没有正确的方法或其他选择?

采纳答案by Jon Skeet

The types in an Object[]will never reallybe primitive - because you've got references! Here the type of iis intwhereas the type of the object referenced by ois Integer(due to auto-boxing).

an 中的类型Object[]永远不会真正原始 - 因为您有引用!这里的类型是iisint而引用的对象的类型oInteger(由于自动装箱)。

It sounds like you need to find out whether the type is a "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;
    }
}

回答by Bombe

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

Integer不是原始人,Class.isPrimitive()不是说谎。

回答by Jose

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.

这是自动装箱。这将解释您收到的输出。Java 1.5 规范中的这个页面更详细地解释了自动装箱。

回答by bruno conde

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

回答by chendral

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;
    }
}
你得到类 test.class 和 javap -c testjavap -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

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

}

如您所见,添加了 java 编译器
invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
从你的 int 创建一个新的 Integer 然后存储 that new Object通过 astore_2 o中的新对象

回答by Michael Myers

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

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

You couldcreate 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.

可以创建一个实用方法来检查对象的类是否为IntegerDouble等。但是无法知道对象是否是通过自动装箱原始对象创建的;一旦被装箱,它看起来就像一个明确创建的对象。

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

因此,除非您确定您的数组在没有自动装箱的情况下永远不会包含包装类,否则没有真正的解决方案。

回答by TofuBeer

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(因为您有足够的答案告诉您为什么它是 false):

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

回答by Steve B.

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

原始包装器类型不会响应此值。这是用于基元的类表示,尽管除了反射之外,我想不出太多的用途。所以,例如

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

prints "false", but

打印“假”,但

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"

打印“真”

回答by Peter Lawrey

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

回答by Matthew Campbell

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

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

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

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