getclass() 返回当前实例在 jvm 中真实的、已加载的 class 对象,即运行时类对象,如 arraylist 和 arraylist 均返回 arraylist.class。

getClass() 不能获取泛型擦除后的实际类型参数,它只返回运行时的原始类对象 —— 比如 ArrayList<string></string> 和 ArrayList<integer></integer> 调用 getClass() 都得到 ArrayList.class。
getClass() 返回的是什么?
getClass() 是 Object 的 final 方法,返回当前实例在 JVM 中真实的、已加载的 Class 对象(即运行时类对象)。它不依赖声明类型,只看实际创建的类型:
-
Object obj = new ArrayList();→obj.getClass()是ArrayList.class,不是Object.class -
List<string> list = new LinkedList();</string>→list.getClass()是LinkedList.class - 子类重写方法不影响结果:
new HashMap().getClass()就是HashMap.class,不是AbstractMap.class
注意:它和 Class.forName("...") 或 SomeClass.class 获取的是同一类对象(同一个 Class 实例),可用于后续反射操作。
用 getClass() 后怎么安全调用反射方法?
拿到 Class 对象后,才能调用 getDeclaredMethod、getDeclaredField 等反射 API。但必须处理好访问权限和异常:
- 私有成员需先调用
setAccessible(true),否则抛IllegalAccessException - 方法/字段不存在会抛
NoSuchMethodException或NoSuchFieldException,建议用 try-catch 包裹 - 调用
invoke()时传参类型必须严格匹配(基本类型不能传包装类,除非自动拆箱发生) - 避免对
null对象调用getClass()—— 会 NPE;可先判空或用Objects.getClass(obj)
示例:获取并调用私有方法
Object instance = new SomeClass();
Class> clazz = instance.getClass();
try {
Method method = clazz.getDeclaredMethod("doWork", String.class);
method.setAccessible(true);
method.invoke(instance, "hello");
} catch (Exception e) {
// 处理 NoSuchMethodException / IllegalAccessException / InvocationTargetException
}
为什么不能靠 getClass() 拿到泛型类型信息?
Java 泛型是编译期特性,运行时已擦除。所以 getClass() 返回的 Class 对象里不含 <t></t> 信息:
-
new ArrayList<string>().getClass()</string>和new ArrayList<integer>().getClass()</integer>结果完全相同 - 想获取泛型参数,得从
Field、Method或ParameterizedType入手(比如通过field.getGenericType()) -
getClass()+getGenericSuperclass()可用于父类带泛型的场景(如继承MyList<string></string>的子类),但这是间接方式,不是getClass()本身的能力
常见误用:试图用 obj.getClass() == ArrayList.class 来判断是否“装了 String”,这毫无意义 —— 类型擦除后根本无从得知。
getClass() 在反射中容易被忽略的细节
几个实战中常踩的点:
-
int.class和Integer.class是不同的Class对象,getClass()对基本类型变量不可用(只能对引用类型调用) - 数组类型有特殊表现:
new String[0].getClass()返回java.lang.String[].class,其getName()是[Ljava.lang.String; - 代理对象(如 Spring AOP 生成的)调用
getClass()返回的是代理类(如$Proxy11.class),不是原始接口或实现类 —— 此时应考虑用AopProxyUtils.ultimateTargetClass()或getInterfaces() - 模块隔离下(Java 9+),不同模块加载的同名类可能不是同一个
Class实例,==判断会失败
真正需要类型精确匹配时,别只盯着 getClass(),多结合 instanceof、isAssignableFrom 和泛型元数据一起分析。










