Java--getClass()和.Class的区别

本文深入讲解Java反射机制,包括反射的基本概念、与传统编程的区别、Class对象的作用及获取方式,并探讨了反射在实际编程中的应用。
复习下反射。在程序运行时期动态获得对象类型信息的操作,对比传统编程和反射的区别。
  • 传统编程:在编译阶段决定使用的类型
  • 反射:动态获得类型
每个类都会产生一个对应的Class对象,也就是保存在.class文件。所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员的引用时,就会加载这个类。Class对象仅在需要的时候才会加载。
类加载器首先会检查这个类的Class对象是否已被加载过,如果尚未加载,默认的类加载器就会根据类名查找对应的.class文件。
获得Class对象的三种方式
  • Object的getClass()
  • 静态加载.class
  • 通过Class的静态方法forName(String className),最为常用
反射通俗理解是把类中各个组成部分映射成一个对象。加载过程:
  1. 反射加载类,JVM会检测是否有.class类文件
  2. 如果没有,则会把.class文件加载从磁盘中加载进内存
  3. 自动创建一个Class对象,通过这个对象可以得到要创建的对象实例

getClass和.Class区别?
我们一般所使用的对象都直接或间接继承自Object类,getClass()是Object类的方法,它可以获得一个实例的类型类。
类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。
public static void main(String[] args) {
    ClassA a=new ClassA();
    System.out.println(a.getClass());
    System.out.println(ClassA.class);
}

对象a是A的一个实例,ClassA是某一个类,在Java中表示一个特定类型的类型类可以用“类型.class”的方式获得,因为a.getClass()获得是ClassA的类型类,也就是ClassA.class。所以ClassA.class和a.getClass()是一样的。
类型类是一一对应的,父类的类型类和子类的类型类是不同的,因此,假设ClassA是ClassB的子类,那么ClassB.class和a.getClass是不一样的。

getClass方法,有多态能力,运行时可以返回子类的类型信息,
.class是没有多态的,是静态解析的,编译时可以确定类型信息。

<think>好的,我现在需要帮助用户在IntelliJ IDEA中设置系统属性-Djava.system.class.loader=kd.bos.security.KDSecurityClassLoader。首先,我得回想一下如何在IDEA中配置运行参数。根据之前的知识,通常在运行配置里可以添加VM选项。用户提供的引用[1]中有一个例子,使用的是命令行方式,但用户想在IDEA里设置,所以应该找类似的配置入口。 接下来,我需要确定用户提到的系统属性是否正确应用。根据Java文档,-Djava.system.class.loader用于指定系统类加载器,这个类必须继承ClassLoader并且有一个接受父类加载器的构造函数。如果用户提供的类KDSecurityClassLoader没有正确实现,可能会导致问题。比如,引用[3]中提到的AppClassLoader需要有父加载器,所以用户的自定义类加载器也需要正确设置父类。 然后,用户可能遇到的常见问题包括类路径配置错误或类加载器实现不符合要求。需要检查是否将包含KDSecurityClassLoader的jar包或类文件正确添加到项目的依赖中。如果类不在classpath中,JVM无法加载,会抛出ClassNotFoundException。引用[2]中的例子展示了类加载器如何输出不同类的加载情况,用户可能需要类似调试来确认自定义加载器是否生效。 另外,引用[4]提到了在IDEA中创建GWT模块,但当前问题与GWT无关,可能是一个干扰信息。但需要注意项目类型是否影响运行配置的位置,比如是否是Maven或Gradle项目,但一般情况下运行配置的设置是相似的。 总结步骤应该是:打开运行配置,在VM选项中添加-Djava.system.class.loader=...,并确保类路径正确。同时提醒用户验证自定义类加载器的实现,特别是构造函数是否正确。可能还需要指导用户如何验证设置是否成功,比如在main方法中打印当前类加载器。</think>### 如何在 IntelliJ IDEA 中设置 `-Djava.system.class.loader`? #### 设置步骤 1. **打开运行配置** - 在 IDEA 的顶部工具栏,点击 `Run` → `Edit Configurations`。 - 选择需要设置的主类(如 `Main` 或具体启动类),若没有则新建一个。 2. **添加 VM 选项** - 在右侧的 `VM options` 输入框中添加: ```bash -Djava.system.class.loader=kd.bos.security.KDSecurityClassLoader ``` - 示例配置参考引用[1],命令行参数与 VM 选项等价。 3. **验证类路径** - 确保 `KDSecurityClassLoader` 类所在的 JAR 包或源码目录已正确添加到项目依赖中。若未添加,系统类加载器无法找到该类,导致启动失败。 4. **运行测试** - 在代码中通过以下语句验证当前系统类加载器: ```java System.out.println(ClassLoader.getSystemClassLoader().getClass().getName()); ``` - 若输出为 `kd.bos.security.KDSecurityClassLoader`,则设置成功[^1]。 --- #### 常见问题及解决 1. **`ClassNotFoundException` 或初始化错误** - **原因**:自定义类加载器未正确实现双亲委派机制,或未调用父类构造方法。 - **解决**:确保 `KDSecurityClassLoader` 继承 `ClassLoader` 且构造函数包含 `parent` 参数,例如: ```java public KDSecurityClassLoader(ClassLoader parent) { super(parent); } ``` 参考引用[3],AppClassLoader 的父加载器需明确指定。 2. **VM 选项未生效** - **检查位置**:确认参数添加在 `VM options` 而非 `Program arguments` 中(两者位置不同)。 3. **类加载器冲突** - **场景**:若项目中存在多个类加载器(如 OSGi、Tomcat),可能覆盖系统属性设置。 - **排查**:通过调试输出所有类加载器的层次结构,确认自定义加载器是否被正确应用[^2]。 --- #### 验证示例代码 ```java public class ClassLoaderTest { public static void main(String[] args) { // 输出系统类加载器类型 System.out.println("System ClassLoader: " + ClassLoader.getSystemClassLoader().getClass().getName()); // 输出当前类的加载器(应为系统类加载器的实例) System.out.println("Current ClassLoader: " + ClassLoaderTest.class.getClassLoader()); } } ``` 若运行结果中 `System ClassLoader` 显示为 `KDSecurityClassLoader`,则配置成功。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值