高级java每日一道面试题-2025年5月02日-基础篇[反射篇-编码]-使用反射,获取Class对象
如果有遗漏,评论区告诉我进行补充
面试官: 编写代码通过三种方式(类名.class
、对象.getClass()
、Class.forName()
)获取java.util.ArrayList
的Class
对象。
我回答:
在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时动态地获取类的信息、操作类的字段和方法等。要使用反射,第一步通常是获取目标类的Class
对象。Java提供了三种常见的方式来获取Class
对象,每种方式都有其适用场景和特点。
一、通过类名.class获取Class对象
这是最直接的方式,适用于在编译期就知道具体类的情况。
Class<?> clazz1 = java.util.ArrayList.class;
System.out.println("类名.class 方式: " + clazz1.getName());
- 优点:代码简洁高效。
- 缺点:只能用于编译期已知类类型的情况。
二、通过对象.getClass()获取Class对象
这种方式适用于你已经拥有某个类的实例,可以通过该实例调用getClass()
方法获得其对应的Class
对象。
java.util.ArrayList<String> list = new java.util.ArrayList<>();
Class<?> clazz2 = list.getClass();
System.out.println("对象.getClass() 方式: " + clazz2.getName());
- 注意:返回的是运行时实际类型的
Class
对象。如果是子类,也会返回子类的Class
。 - 例如:
List<String> list = new ArrayList<>(); System.out.println(list.getClass().getName()); // 输出的是 java.util.ArrayList
三、通过Class.forName()获取Class对象
这是一种在运行时动态加载类的方式,特别适用于需要根据字符串类名加载类的场景(如配置文件、插件系统等)。
try {Class<?> clazz3 = Class.forName("java.util.ArrayList");System.out.println("Class.forName() 方式: " + clazz3.getName());
} catch (ClassNotFoundException e) {e.printStackTrace();
}
- 注意:必须捕获或抛出
ClassNotFoundException
。 - 该方法还会触发类的静态初始化块执行(如果有的话)。
完整示例代码
import java.util.ArrayList;public class GetClassDemo {public static void main(String[] args) {try {// 方式一:类名.classClass<?> clazz1 = ArrayList.class;System.out.println("类名.class: " + clazz1.getName());// 方式二:对象.getClass()ArrayList<String> list = new ArrayList<>();Class<?> clazz2 = list.getClass();System.out.println("对象.getClass(): " + clazz2.getName());// 方式三:Class.forName()Class<?> clazz3 = Class.forName("java.util.ArrayList");System.out.println("Class.forName(): " + clazz3.getName());} catch (ClassNotFoundException e) {System.err.println("找不到指定类!");e.printStackTrace();}}
}
总结:三种方式对比
获取方式 | 示例代码 | 是否需要实例 | 是否需处理异常 | 常见用途 |
---|---|---|---|---|
类名.class | ArrayList.class | 否 | 否 | 编译期已知类 |
对象.getClass() | list.getClass() | 是 | 否 | 运行时获取对象的实际类型 |
Class.forName() | Class.forName("java.util.ArrayList") | 否 | 是(ClassNotFoundException ) | 动态加载类,常用于框架 |
小贴士
- 所有这三种方式获取到的
Class
对象都是同一个(对于同一个类),它们都指向JVM中唯一的类元数据。 - 如果你在开发框架、ORM、依赖注入容器、注解处理器等工具时,这些技巧非常重要。
通过上述三种方式,你可以灵活选择适合当前上下文的方式来获取Class
对象,以满足不同的开发需求。每种方式都有其适用场景,合理选择可以提升代码的灵活性和效率。