1. 概述

在开发中,我们有时需要判断一个对象是否属于基本类型(primitive type),尤其是处理基本类型的包装类时。虽然 Java 的标准库没有直接提供判断“某对象是否为基本类型或其包装类”的工具方法,但我们可以通过一些手段实现。

本文将介绍如何使用纯 Java 实现这一功能,然后对比两个常用第三方库(Apache Commons 和 Guava)提供的解决方案。✅

2. 基本类型与包装类

Java 中有 8 个基本类型(int, boolean, char 等),每个都有对应的包装类(Wrapper Class),如 Integer, Boolean, Character 等。此外还有一个特殊的 Void 类型。

Java 提供了 Class.isPrimitive() 方法来判断某个 Class 是否为基本类型:

int.class.isPrimitive();     // true
Integer.class.isPrimitive(); // false ❌

⚠️ 注意:isPrimitive() 只对原始类型返回 true,对包装类无效。这意味着我们不能直接用它来判断一个 Integer 对象是不是“代表基本类型的类”。

所以,如果我们想统一判断一个对象是否“属于基本类型体系”(包括原始类型和包装类),就需要自己动手了。

3. 使用原生 Java 实现

一个简单粗暴但高效的方式是:预先建立包装类到原始类型的映射表

我们用一个静态的 HashMap 存储所有包装类与其对应的基本类型:

private static final Map<Class<?>, Class<?>> WRAPPER_TYPE_MAP;
static {
    WRAPPER_TYPE_MAP = new HashMap<Class<?>, Class<?>>(16);
    WRAPPER_TYPE_MAP.put(Integer.class, int.class);
    WRAPPER_TYPE_MAP.put(Byte.class, byte.class);
    WRAPPER_TYPE_MAP.put(Character.class, char.class);
    WRAPPER_TYPE_MAP.put(Boolean.class, boolean.class);
    WRAPPER_TYPE_MAP.put(Double.class, double.class);
    WRAPPER_TYPE_MAP.put(Float.class, float.class);
    WRAPPER_TYPE_MAP.put(Long.class, long.class);
    WRAPPER_TYPE_MAP.put(Short.class, short.class);
    WRAPPER_TYPE_MAP.put(Void.class, void.class);
}

有了这个映射表,我们就可以通过判断对象的 Class 是否存在于 key 中,来确认它是否为包装类。

封装成工具方法:

public static boolean isPrimitiveType(Object source) {
    return source != null && WRAPPER_TYPE_MAP.containsKey(source.getClass());
}

📌 注意:加上 source != null 防止空指针。

测试一下:

assertTrue(PrimitiveTypeUtil.isPrimitiveType(false));           // Boolean 实例
assertTrue(PrimitiveTypeUtil.isPrimitiveType(1L));              // Long 实例
assertFalse(PrimitiveTypeUtil.isPrimitiveType(StringUtils.EMPTY)); // String,非基本类型

✅ 成功识别包装类实例。这个方案不依赖外部库,适合轻量级项目或不想引入依赖的场景。

4. 使用 Apache Commons — ClassUtils.isPrimitiveOrWrapper()

Apache Commons Lang 是 Java 开发中的“瑞士军刀”,其中 ClassUtils.isPrimitiveOrWrapper() 方法就是为此类需求设计的。

先引入依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

使用方式非常直观:

assertTrue(ClassUtils.isPrimitiveOrWrapper(Boolean.FALSE.getClass())); // true
assertTrue(ClassUtils.isPrimitiveOrWrapper(boolean.class));             // true
assertFalse(ClassUtils.isPrimitiveOrWrapper("hello".getClass()));       // false

✅ 支持原始类型和包装类,语义清晰,推荐在已使用 Commons 的项目中直接采用。

5. 使用 Guava — Primitives.isWrapperType()

Google Guava 也提供了类似能力,通过 Primitives.isWrapperType() 判断某个类是否为基本类型的包装类。

先加依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

测试代码:

assertTrue(Primitives.isWrapperType(Boolean.FALSE.getClass())); // true
assertFalse(Primitives.isWrapperType("test".getClass()));        // false

⚠️ 但注意:isWrapperType() 只认包装类,不认原始类型

assertFalse(Primitives.isWrapperType(boolean.class)); // 返回 false!

所以如果你需要同时支持 boolean.classBoolean.class不能直接用这个方法,得自己包装一层:

public static boolean isPrimitiveOrWrapper(Class<?> cls) {
    return cls != null && (cls.isPrimitive() || Primitives.isWrapperType(cls));
}

6. 总结

方式 是否支持原始类型 是否支持包装类 是否推荐
自定义 HashMap 映射 ❌(需额外判断) ✅ 小项目可用
Apache Commons ClassUtils.isPrimitiveOrWrapper() ✅✅ 强烈推荐
Guava Primitives.isWrapperType() ⚠️ 需配合 isPrimitive() 使用

📌 最佳实践建议:

  • 已引入 Commons Lang3:直接用 ClassUtils.isPrimitiveOrWrapper(),简单可靠。
  • 只用了 Guava:结合 cls.isPrimitive() || Primitives.isWrapperType(cls)
  • 不想加依赖:手写映射表,注意 null 安全。

完整代码示例可参考:GitHub - core-java-lang-oop-types


原始标题:Determine if an Object Is of Primitive Type