确定对象是否是基本类型

dri*_*l3r 109 java reflection

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

int i = 3;
Object o = i;

System.out.println(o.getClass().getName() + ", " +
                   o.getClass().isPrimitive());
Run Code Online (Sandbox Code Playgroud)

打印java.lang.Integer, false.

有正确的方法或替代方案吗?

Jon*_*eet 161

一个中的类型Object[]永远不会真正原始 - 因为你有参考!这里的类型i是,int而引用的对象的类型oInteger(由于自动装箱).

听起来你需要找出这个类型是否是"原始包装".我不认为标准库中有任何内置,但编码很容易:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @NateS:我相信它更具可读性,这就是为什么我会使用它来代替"if"语句,直到**被证明*集合的开销是一个实际的瓶颈. (8认同)
  • 我想知道使用HashSet的开销是否真的比几个if语句好. (3认同)
  • @NateS `HashSet` 允许在 O(1) 中访问,而一行 `if` 语句或 `switch` 语句在最坏的情况下需要 O(# of wrappers)。实际上,对于固定数量的 9 个包装器的 `if` 语句是否可能并不比基于哈希的访问更快,这是值得怀疑的。 (2认同)

Boz*_*zho 76

commons-lang ClassUtils有相关的方法.新版本有:

boolean isPrimitiveOrWrapped = 
    ClassUtils.isPrimitiveOrWrapper(object.getClass());
Run Code Online (Sandbox Code Playgroud)

旧版本有wrapperToPrimitive(clazz)方法,它将返回原始对应关系.所以你可以这样做:

boolean isPrimitiveOrWrapped = 
    clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
Run Code Online (Sandbox Code Playgroud)

  • Spring也有[ClassUtils](http://docs.spring.io/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/util/ClassUtils.html#isPrimitiveOrWrapper(java.lang.Class)) class,所以如果你已经使用Spring,它会更方便. (7认同)
  • 这不是 [直到 v3.1 添加](https://issues.apache.org/jira/browse/LANG-756),您的链接反映了 2.5 API。我已经改正了。 (2认同)

And*_*ejs 25

Google的Guava库有一个Primitives实用程序,用于检查类是否是基元的包装类型:http: //guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/primitives/Primitives.html

__PRE__

Class.isPrimitive()适用于基元

  • someObject.getClass().isPrimitive() (4认同)

Pet*_*rey 16

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • @Shervin`void.class.isPrimitive()`返回true (2认同)
  • Void 是空的,“Void”的唯一有效值是“null”;)它对于创建“Callable&lt;Void&gt;”非常有用,它是一个不返回任何内容的 Callable。 (2认同)

Jos*_*ose 8

从Java 1.5及更高版本开始,有一个名为auto-boxing的新功能.编译器本身就是这样做的.当它看到机会时,它会将原始类型转换为适当的包装类.

这里可能发生的是你宣布的时候

Object o = i;
Run Code Online (Sandbox Code Playgroud)

编译器将编译此语句

Object o = Integer.valueOf(i);
Run Code Online (Sandbox Code Playgroud)

这是自动拳击.这可以解释您收到的输出.Java 1.5规范中的这个页面更详细地解释了自动装箱.

  • 不完全正确.它不是一个新的Integer,而是调用Integer.valueOf(int),它对Integer实例进行一些缓存. (5认同)

Bom*_*mbe 6

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


bru*_*nde 5

我认为这是因为自动拳击而发生的.

int i = 3;
Object o = i;
o.getClass().getName(); // prints Integer
Run Code Online (Sandbox Code Playgroud)

您可以实现一个匹配这些特定装箱类的实用程序方法,并为您提供某个类是否为原始类.

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 你可以安全地将`.equals`改为`==`.课程是单身人士. (5认同)

che*_*ral 5

你必须处理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

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,然后通过astore_2 将该新对象存储在o中


小智 5

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;
}
Run Code Online (Sandbox Code Playgroud)