Java中的鸡肉或鸡蛋困境

时间:2013-01-19 21:08:17

标签: java design-patterns

Object位于Java类的顶部。 String是Object的子类。

那么,首先是什么 - 对象或字符串?

提示答案是 - 对象。

但有趣的是,Object已经有一个方法toString(),因此“知道”了String。因此,构造Object时,String必须已经存在。另一方面,String是Object的子类,当构造String时,Object必须已经存在。我们陷入了永无止境的定义循环(以及一些技术问题)。这种方法至少违反了单个根类的想法。

这种关注可能看起来像是理论上的,而不是实际的。

但问题是我在其他框架中看到了类似的方法。 我认为至少在一定程度上它受到了核心Java类设计方式的启发。

您如何看待 - 一般来说Java类之间的循环依赖性(特别是在Object / String的情况下)是不可避免的? 不应该不惜一切代价避免它们吗? 或者,由于合理的妥协,他们有时可以接受(谨慎和谨慎)吗?如果,那么 - 标准是什么?

5 个答案:

答案 0 :(得分:5)

Java没有单程编译器,而是多遍编译器。

这意味着所有编译在一起的类实际上都处于声明级别。即使它们具有循环依赖关系,它们也会在第一步中得到解决,因此Object类提供toString方法的事实在概念上并不意味着与根类相关的任何内容。

由于我们讨论的是理论问题,因此很容易解决类声明和真正的根类之间的关系:

Object是根类,只是因为String继承了它。

String toString()只不过是一个对编译器授予类型安全性有用的签名,Object不需要String个对象,它甚至不需要知道String是什么。

答案 1 :(得分:1)

由于Object和String都是Java的第一个版本,我认为它们都是同时出现的。

答案 2 :(得分:1)

我认为之间的循环依赖关系不一定是个问题,并且经常发生(出于可靠的设计原因)。假设您有一个树和一个相互了解的节点,或链接列表和节点等。在这种情况下,循环依赖是完全合理的。

我不太喜欢 modules 之间的循环依赖关系。在我看来,这些通常可以避免。

答案 3 :(得分:1)

正如您所描述的那样“问题”听起来好像您认为Java是一种脚本语言,其中必须首先声明Java才能在其范围内,但事实并非如此,因为Java是编译的语言,这意味着这种依赖关系在编译时解决。

答案 4 :(得分:0)

没有矛盾。

Object指的是自身的子类。这不是非法的,因为与鸡肉不同,字符串不必由对象“开发”,它们的类只需要Object类进行构造,因此两者都必须在编译时可用。

如果你想要鸡蛋混淆,请看看Smalltalk:它使用Metaclass对象等,这是一个非常好的例子,几乎所有语言都可以实现。