关于java:使用final属性扩展类。 小样

Extending a class with final attributes. Mockup

我通常将类的每个属性设置为final(仅适用于将在构造函数中初始化的属性)。
关键是我现在正在实现一个用于测试目的的对象的样机。这个Mockup扩展了它正在模拟的类,这个类有一些最终的属性。因此,我被迫在Mockup对象的构造函数中调用super()构造函数。这打破了Mockup的实用程序,因为我不希望它以普通类的方式初始化所有属性。我宁愿调用Mockup构造函数而不调用super()并做任何我想做的事情。

我的问题是:将属性定义为final是一个好习惯,只要它们会强制你调用Mockup中的类构造函数吗?

编辑:我添加一些代码。在这种情况下的问题是我使用单例,我知道这在测试时不是一个好主意,但在这种情况下我不能改变它。所以我的目的不是在模型中调用这个方法。

1
2
3
4
5
6
7
public class ReportsDataManager {

private final Map<String, List<String>> translations;

public ReportsDataManager() {
this.translations = GenericUtils.getTranslation();
}

}


当你可以做到时,声明属性final是一个非常好的做法。它赋予了不变性 - 保证线程安全。打破它来模拟是一个坏主意。您的设计应该满足用户的需求,而不是您的测试方便性。


如果你想模拟这个类,给它一个接口并模拟接口。此外,模拟不是存根。听起来你正在创建一个存根,而不是一个模拟。
如果您确实希望创建模拟,请选择一个为您生成接口模拟的库。


您可以使用标准反射来回避final限制。因为你是在一个模型的上下文中,所以这不会引起太多问题,我想。只要注意多线程问题:JVM将假设该字段遵循final语义并将考虑到这一点进行优化。


一般来说,如果你使用的练习使你的代码测试更加困难,那么这种做法可能就是一种气味。

尝试通过设置变量final来确定您想要实现的目标。 protected会被接受吗?