无参数构造函数是必需的(像 Hibernate 这样的工具在这个构造函数上使用反射来实例化对象)。
我得到了这个简单的回答,但有人可以进一步解释吗?谢谢
原文由 unj2 发布,翻译遵循 CC BY-SA 4.0 许可协议
无参数构造函数是必需的(像 Hibernate 这样的工具在这个构造函数上使用反射来实例化对象)。
我得到了这个简单的回答,但有人可以进一步解释吗?谢谢
原文由 unj2 发布,翻译遵循 CC BY-SA 4.0 许可协议
呃,对不起大家,但是 Hibernate 并不 要求你的类必须有一个无参数的构造函数。 JPA 2.0 规范 要求它,这对 JPA 来说是非常蹩脚的。 JAXB 等其他框架也需要它,这对于那些框架来说也是非常蹩脚的。
(实际上,JAXB 应该允许实体工厂,但它坚持自己实例化这些工厂,要求它们有一个——猜猜看——无 _参数构造函数_,在我的书中,这与不允许工厂一样好;这是多么蹩脚!)
但是 Hibernate 不需要这样的东西。
Hibernate 支持拦截机制(请参阅 文档中的“拦截器” ),它允许您使用对象需要的任何构造函数参数来实例化对象。
基本上,你所做的是,当你设置休眠时,你传递给它一个实现 org.hibernate.Interceptor
接口的对象,然后休眠将调用 instantiate()
该接口的方法,只要它需要一个新的你的一个对象的实例,所以你对该方法的实现可以 new
你的对象以你喜欢的任何方式。
我已经在一个项目中完成了它,它就像一个魅力。在这个项目中,我尽可能通过 JPA 做事,并且我只在没有其他选择时使用拦截器等 Hibernate 功能。
Hibernate 似乎对此有些不安全,因为在启动期间它会为我的每个实体类发出一条信息消息,告诉我 INFO: HHH000182: No default (no-argument) constructor for class
和 class must be instantiated by Interceptor
,但稍后我会实例化它们通过拦截器,它对此很满意。
要回答 除 Hibernate 以外 的工具问题的“为什么”部分,答案是“绝对没有充分的理由”,而 hibernate 拦截器的存在证明了这一点。有许多工具本来可以支持一些类似的客户端对象实例化机制,但它们没有,所以它们自己创建对象,所以它们必须需要无参数构造函数。我很想相信这种情况正在发生,因为这些工具的创建者认为自己是忍者系统程序员,他们创建了充满魔力的框架供无知的应用程序程序员使用,他们(他们认为)永远不会在他们最疯狂的梦想中拥有需要诸如… 工厂模式 之类的高级构造。 (好吧,我 很想 这么想。我 实际上并不 这么认为。我是在开玩笑。)
原文由 Mike Nakis 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
2 回答931 阅读✓ 已解决
1 回答656 阅读
2 回答479 阅读✓ 已解决
1 回答630 阅读
2 回答661 阅读✓ 已解决
Hibernate 和通过反射创建对象的一般代码使用
Class<T>.newInstance()
创建类的新实例。此方法需要公共无参数构造函数才能实例化对象。对于大多数用例,提供无参数构造函数不是问题。有一些基于序列化的 hack 可以解决没有无参数构造函数的问题,因为序列化使用 jvm magic 来创建对象而不调用构造函数。但这并非在所有 VM 中都可用。例如, XStream 可以创建没有公共无参数构造函数的对象实例,但只能通过在仅在某些 VM 上可用的所谓“增强”模式下运行。 (有关详细信息,请参阅链接。)Hibernate 的设计者肯定选择保持与所有 VM 的兼容性,因此避免了此类技巧,并使用了官方支持的反射方法
Class<T>.newInstance()
需要无参数构造函数。