Java中MyClass.class与this.getClass()的功能差异及选型技术考量
Java Logger两种初始化方式的技术差异与选择理由
一、两种初始化写法示例
写法1:显式指定类名
public class MyClass extends OtherClass { private final Logger LOGGER = LoggerFactory.getLogger(MyClass.class); // ... }
写法2:通过this.getClass()获取类对象
public class MyClass extends OtherClass { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); // ... }
二、技术层面的核心差异与优势
1. 子类继承场景的行为不同
如果MyClass存在子类SubClass,两种写法的日志归属会有明显区别:
- 写法1的Logger始终绑定
MyClass.class,无论创建的是父类还是子类实例,日志都会标记为MyClass; - 写法2的Logger会绑定实例的实际类型,创建子类实例时,日志会自动标记为
SubClass。
这意味着:
- 写法1适合需要父类日志统一归属的场景,比如父类工具类的日志不想被子类分散;
- 写法2适合需要区分不同子类日志的场景,无需在子类中重复定义Logger。
2. 运行时开销的细微差别
- 写法1中,
MyClass.class是编译期常量,JVM在类加载阶段就会确定对应的Class对象,初始化Logger时没有额外方法调用; - 写法2中,
this.getClass()是运行时方法调用,需要通过实例获取其实际类型,虽然单次调用开销极小,但在需要大量创建类实例的高频场景下,累计开销可能会有可观测的差异。
3. 编译期检查与静态场景兼容性
- 写法1如果写错类名(比如误写为
MyClas.class),编译阶段就会直接报错,能提前发现错误; - 写法2不会出现类名拼写错误,但无法用于静态Logger的初始化(静态字段初始化时
this尚未存在,会直接编译报错),而写法1可以正常用于静态Logger的定义。
4. 类初始化阶段的安全性
在一些特殊的类初始化场景(比如通过反射触发类加载),this可能还未完成初始化,虽然Logger实例字段的初始化时机通常不会触发这类问题,但写法1完全依赖编译期常量,不存在任何潜在的初始化安全风险。
三、选择建议
- 若希望日志自动跟随子类类型、避免复制粘贴时的类名错误,优先选择写法2;
- 若需要固定日志归属父类、用于静态Logger定义、追求极致的初始化性能,优先选择写法1;
- 绝大多数普通业务场景中,两种写法的差异可以忽略,直接遵循团队编码规范即可。
内容的提问来源于stack exchange,提问作者schnejj
相关产品推荐
相关产品推荐

