1. 简介
本文将介绍在 Groovy 中判断数据类型的几种常用方式。
需要注意的是,不同场景下的处理方式略有差异:
- ✅ 基本类型(Primitives)的类型判断
- ✅ 集合类型(Collections)的特殊处理
- ✅ 对象与类变量的类型获取
掌握这些技巧,能帮你少踩不少坑,尤其是在动态类型和静态类型混用的 Groovy 项目中。
2. 基本类型
Groovy 支持与 Java 相同的原始数据类型。对于基本类型,我们有三种方式来判断其数据类型:
2.1 使用 instanceof
操作符
这是最直观的方式,用于判断某个变量是否为指定类型:
@Test
public void givenWhenParameterTypeIsInteger_thenReturnTrue() {
Person personObj = new Person(10)
Assert.assertTrue(personObj.ageAsInt instanceof Integer);
}
✅
instanceof
是 Java 和 Groovy 共有的二元操作符,返回布尔值。
⚠️ 注意:Groovy 3 引入了!instanceof
操作符,用于判断“不是某个类型”,使用时注意版本兼容性。
2.2 调用 getClass()
方法
通过对象的 getClass()
方法获取其运行时类:
def "givenWhenParameterTypeIsDouble_thenReturnTrue"() {
given:
Person personObj = new Person(10.0)
expect:
personObj.ageAsDouble.class == Double
}
2.3 使用 .class
操作符
Groovy 中可以直接对变量使用 .class
获取类型:
def "givenWhenParameterTypeIsString_thenReturnTrue"() {
given:
Person personObj = new Person("10 years")
expect:
personObj.ageAsString.class == String
}
✅ 三种方式均可用于基本类型,推荐优先使用
getClass()
,更安全、语义清晰。
3. 集合类型
Groovy 对集合(List、Map 等)提供了原生支持,但类型判断时需格外小心,尤其是 .class
的使用。
3.1 List 类型判断
List 在 Groovy 中默认是 ArrayList
,可以通过 .class
或 getClass()
获取类型:
def "givenGroovyList_WhenFindClassName_thenReturnTrue"() {
given:
def ageList = ['ageAsString', 'ageAsDouble', 10]
expect:
ageList.class == ArrayList
ageList.getClass() == ArrayList
}
✅ 这里 .class
和 getClass()
效果一致,都能正确返回 ArrayList
。
3.2 Map 类型的坑 ❌
⚠️ 对 Map 使用 .class
会出问题!看下面例子:
@Test
public void givenGrooyMap_WhenFindClassName_thenReturnTrue() {
def ageMap = [ageAsString: '10 years', ageAsDouble: 10.0]
Assert.assertFalse(ageMap.class == LinkedHashMap)
}
❌ 为什么失败?
因为ageMap.class
并不会返回 Map 的类类型,而是尝试从 Map 中获取 key 为"class"
的值!
Groovy 会把.class
当作 Map 的 key 来查找,而不是调用类方法。
✅ 正确做法:对 Map 必须使用 getClass()
assert ageMap.getClass() == LinkedHashMap
💡 小结:
- List:
.class
和getClass()
都行- Map:**必须用
getClass()
**,.class
会踩坑!
4. 对象与类变量
除了变量实例,我们有时还需要在反射层面获取类字段的类型信息。
4.1 获取类字段的类型
假设我们有如下 Person
类:
class Person {
int ageAsInt
double ageAsDouble
String ageAsString
}
我们可以通过反射获取字段的类型:
def "givenClassName_WhenParameterIsInteger_thenReturnTrue"() {
expect:
Person.class.getDeclaredField('ageAsInt').type == int.class
}
✅
getDeclaredField()
获取指定字段,.type
返回其 Class 类型。
这在元编程或构建通用工具时非常有用。
4.2 判断对象类型
对于对象实例,依然可以使用前面提到的方式:
def "givenWhenObjectIsInstanceOfType_thenReturnTrue"() {
given:
Person personObj = new Person()
expect:
personObj.class == Person
}
4.3 使用 in
操作符判断继承关系
Groovy 提供了 in
操作符,可用于判断类型归属,尤其适合判断子类:
def "givenWhenInstanceIsOfSubtype_thenReturnTrue"() {
given:
Student studentObj = new Student()
expect:
studentObj.class.superclass == Person
}
✅ 虽然
in
更常用于集合遍历,但在类型判断中结合class
和superclass
也能派上用场。
5. 总结
本文系统梳理了 Groovy 中判断数据类型的几种方式:
方式 | 适用场景 | 推荐度 | 注意事项 |
---|---|---|---|
instanceof |
类型判断 | ✅ | 支持 !instanceof (Groovy 3+) |
getClass() |
任意对象,最安全 | ✅✅✅ | 推荐优先使用,尤其对 Map |
.class |
基本类型、List | ✅ | ❌ 不要用于 Map |
getDeclaredField().type |
反射获取字段类型 | ✅ | 适用于元编程场景 |
in + class |
类型归属判断 | ✅ | 结合继承关系使用 |
✅ 最佳实践建议:
- 统一使用
getClass()
,避免.class
在 Map 上的陷阱- 反射场景用
.type
获取字段类型- 多态判断结合
instanceof
和superclass
所有示例代码已托管至 GitHub:https://github.com/baeldung/core-groovy-modules/core-groovy-2