This talk描述了Java StructuredArray
的设计。一切都很清楚,除了东西:
它不应该是可构造的,即实例可能只能通过某些静态工厂方法获得,如newInstance。同时,它们应该是子类,这意味着必须有一个公共构造函数,并且在运行时将确保不可构造性。这听起来非常hacky,所以我想知道为什么?
我了解工厂的一般优势和静态工厂方法。但是我们得到了什么,这样才能让黑客接受?
答案 0 :(得分:3)
StructuredArray
类的要点是,有一天它可以被一个内部实现替换,该实现将整个数组(包括组件对象)分配为一个长内存块。 当发生这种情况时,对象的大小将取决于元素的数量和元素类。
如果StructuredArray
有公共构造函数,那么您可以编写x = new StructuredArray<>(StructuredArray.class, MyElement.class, length)
。这似乎没有任何问题,除了在字节码中,这变成了分配对象的new
指令,然后是单独的 {{ 1}}调用对象构造函数的指令。
您看到问题 - invokespecial
指令必须分配对象,但不能,因为对象的大小取决于构造函数参数(元素类和长度)它没有!直到稍后的构造函数调用之后才会传递它们。
有很多方法可以解决这类问题,但它们都有点粗糙。将构造封装在静态工厂方法中更有意义,因为那时你只是无法编写 new
,并且JVM不必使用任何“魔法”来计算new StructuredArray...
new
指令中要分配的内存量,因为不能有任何此类指令*。
如果某个后来的JVM想要提供分配连续数组的静态工厂的内部实现,那么它就没问题了 - 它在工厂方法调用中获取了所需的所有信息。
NB * - 是的,好的,从技术上讲,你可以写StructuredArray
,但它不会为你提供有用的对象。
答案 1 :(得分:2)
语义通过API文档,我的理解是它主要是一个Semantics的问题。并提供Fluent API。此外,如果您转到演示文稿的结论幻灯片,您应该注意到Semantics项目符号首先出现(如果我们不计算源代码URL)。
如果我们选择正常的数组。它们提供了明确的语义:
结果
我们有一个使用数组的统一模型。 API非常清晰。没有10种不同的方法来处理数组。我相信对于Java语言开发人员来说,api的这种清洁是非常重要的。强制不可构造性,它们隐含地迫使我们按照他们希望我们使用它的方式使用API。
<强>建筑强>
由于StructuredArray本质上也是数组。提出一个构造函数会立即迫使我们使用StructuredArray的Concrete实现,它会自动引入问题,引入这个统一的&#34;&#34;数组究竟是什么?&#34;
这就是为什么通过Javadoc我们可以看到StructuredArray实际构建的方式:
static <S extends StructuredArray<T>,T> S newInstance(java.lang.invoke.MethodHandles.Lookup lookup,
java.lang.Class<S> arrayClass,
java.lang.Class<T> elementClass,
java.util.Collection<T> sourceCollection)
这里可见的是StructuredArray强制执行以下操作:
我相信有一个非常强大的语义符号,而且作者正在给我们一个很好的暗示如何编码应该发生。
结构化数组的另一个有趣特性是能够传递构造函数。我们再次讨论了接口和API与实际实现的强大分离。
数组模型
通过检查 StructuredArrayModel 进一步确认了我的话 http://objectlayout.github.io/ObjectLayout/JavaDoc/index.html?org/ObjectLayout/StructuredArray.html
StructuredArrayModel(java.lang.Class<S> arrayClass, java.lang.Class<T> elementClass, long length)
构造函数可以看到三件事: - 数组类 - 元素的类型 - 长度
进一步观察结构化阵列支持的结构:
An array of structs: struct foo[]; A struct with a struct inside: struct foo { int a; bar b; int c; }; A struct with an array at the end: struct foo { int len; char[] payload; };
StructuredArrayModel 完全支持它 与StructuredArray相比,我们能够轻松实例化模型的具体实现。
StructuredArray向我们展示了传递伪构造函数http://objectlayout.github.io/ObjectLayout/JavaDoc/org/ObjectLayout/CtorAndArgs.html
的能力newInstance(CtorAndArgs<S> arrayCtorAndArgs, java.lang.Class<T> elementClass, long length)