This talk在34:00描述了Java的StructuredArray的设计。一切都很清楚,除了事情:

它不应是可构造的,即该实例只能通过某些静态工厂方法(例如newInstance)获得。同时,它们应该是可子类化的,这意味着必须有一个公共构造函数,并且在运行时将确保不可构造性。这听起来很hacky,所以我想知道为什么吗?

我知道一般工厂尤其是静态工厂方法的优势。但是,我们在这里能得到什么,从而使黑客可以接受?

最佳答案

StructuredArray类的要点是,有一天可以将其替换为一个内部实现,该实现将整个数组(包括组件对象)分配为一个长内存块。发生这种情况时,对象的大小将取决于元素的数量和元素类。

如果StructuredArray具有公共构造函数,则可以编写x = new StructuredArray<>(StructuredArray.class, MyElement.class, length)。这似乎没有任何问题,只是在字节码中,这变成了分配对象的new指令,然后是单独的invokespecial指令来调用对象的构造函数。

您会看到问题-new指令必须分配对象,但不能分配对象,因为对象的大小取决于它没有的构造函数参数(元素类和长度)!直到某个时间之后的构造函数调用之后,这些参数才被传递。

有一些方法可以解决这样的问题,但是它们都是毛病。在静态工厂方法中封装构造更有意义,因为那样您就不能编写new StructuredArray...,并且JVM不必使用任何“魔术”来计算new指令中要分配多少内存。用于StructuredArray,因为根本没有任何此类说明*。

如果以后有一些JVM想提供分配连续数组的静态工厂的内部实现,那么没问题-它在工厂方法调用中获取了所需的所有信息。

NB *-是的,好的,从技术上讲,您可以编写new StructuredArray...,但是它对您没有帮助。

10-05 20:12