为了账号安全,请及时绑定邮箱和手机立即绑定

为什么要用Java声明一个不变的类final?

为什么要用Java声明一个不变的类final?

长风秋雁 2019-11-27 10:02:20
我读到要使一个类在Java中不可变,我们应该执行以下操作,不提供任何二传手将所有字段标记为私有最终上课为什么需要步骤3?我为什么要标记课程final?
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

相反的是,许多人认为,做一个不变类final是不必需的。


制作不可变类的标准论点final是,如果不这样做,则子类会增加可变性,从而违反了超类的约定。班级的客户将承担不变性,但是当某些东西从他们的底下变异出来时,他们会感到惊讶。


如果将此参数推至逻辑极限,则应采用所有方法final,否则子类可能以不符合其超类协定的方式覆盖方法。有趣的是,大多数Java程序员都认为这很荒谬,但是对于不可变的类应该是的想法还是可以接受的final。我怀疑这与Java程序员有关,总的来说,他们对不可变性的概念并不完全满意,也许与finalJava关键字的多种含义有关的某种模糊思维。


符合您的超类的约定不是编译器可以或应该始终执行的。编译器可以执行合同的某些方面(例如:最少的一组方法及其类型签名),但是编译器无法执行典型合同的许多部分。


不变性是集体合同的一部分。这与人们更习惯的一些操作有所不同,因为它说明了类(以及所有子类)不能做什么,而我认为大多数Java(通常是OOP)程序员倾向于将合同与一个班级可以做什么,而不是它不能做什么。


不变性不仅会影响单个方法,而且会影响整个实例,但这equals与hashCodeJava的工作方式和方式并没有太大不同。这两种方法在中都有特定的合同Object。该合同非常仔细地列出了这些方法无法完成的工作。该合同在子类中更加具体。这很容易被覆盖equals或hashCode违反合同。实际上,如果您仅覆盖这两种方法中的一种而没有另一种,则很可能违反了合同。所以应该equals和hashCode已经宣布final在Object避免这种情况?我认为大多数人会认为他们不应该这样做。同样,也不必制作不可变的类final。


也就是说,您的大多数类(无论是否不变)都应该是final。请参见有效的Java第二版项目17:“设计和记录继承,否则禁止继承”。


因此,第3步的正确版本是:“将类定型,或者在设计子类时,明确记录所有子类必须继续保持不变。”


查看完整回答
反对 回复 2019-11-27
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

不要将整个课程都标记为决赛。

有充分的理由允许如其他答案中所述扩展不可变的类,因此将类标记为final并非总是一个好主意。

最好将您的资产标记为私有和最终资产,如果您想保护“合同”,则将获取者标记为最终资产。

这样,您可以允许扩展类(即使是可变的类也可以),但是可以保护类的不可变方面。属性是私有的,无法访问,这些属性的吸气剂是最终的,不能被覆盖。

使用您的不可变类实例的任何其他代码都将能够依赖于类的不可变方面,即使所传递的子类在其他方面是可变的。当然,由于它需要一个类的实例,所以甚至不知道这些其他方面。


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 599 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信