java 解决父构造器中拿到对象
这两天被问到一个有意思的问题,就是如果在构造器中拿到匿名对象。
这个问题有意思在,直觉上是可以通过外部放一个成员变量去接,然后后续就可以使用了,但实际不行。
问题复现
下面这个是构造器,当通过 supper 去调用父类构造器。由于问题出现在Spring项目当中,所以我复现的例子也基于Spring重新搭了一个项目来复现这个过程,代码放github上。
复现demo:
1 | package com.test; |
1 | public class TxCacheDB { |
这里可以偿试几种解决方案:
- 方案一
直接成员变量中 new TxCacheDB(dbName); 构造器中再使用 - 方案二
super调用一个方法,而不直接new TxCacheDB(); - 方案三
将对象保在ThreadLocal中,再拿出来
验证方案
方案一
这种在直觉上没有问题,但是实际有问题:
- 成员变量不知道 dbName,传入的具体值是什么,如果写死就失去灵活性。
- 写死。如果写死,你不能确定会传入dbName将会是什么,实际中这个dbName有很多个,没有办法写死
方案二
这个方法看着就可行,来验证一下。
1 | import org.springframework.beans.factory.annotation.Autowired; |
输出结果:
TxCacheDB: trans-cache
TxCacheDB: init
结查证明可行。
但是有个问题,我就用一次,还有开辟一段元数据区态内存来放 这个 static TxCacheDB,不划算。
我就想用一次,不想还占用内存。
方案三
将对象放入本地线程中,使用后就移除。
这样即可以使用对象,也不需要一直占用部分内存。
1 | public class TransactionCache3 extends RevokingDB { |
TxCacheDB: trans-cache3
TxCacheDB: init
总结
java 对象在初始化的时候构造器中 supper 是永远放在第一行不能变。这一特性决定了这个问题的解决只能曲线救国。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 人话翻译机!
评论