3

34:00 からのこの講演StructuredArrayでは、Java 用の s の設計について説明します。物事を除いて、すべてがかなり明確です:

つまり、インスタンスは、newInstanceなどの静的ファクトリ メソッドによってのみ取得可能である可能性があります。同時に、それらはサブクラス化可能である必要があります。つまり、パブリック コンストラクターが存在する必要があり、実行時に非構築可能性が保証されます。これは非常にハックに聞こえるので、なぜだろうか?

一般的なファクトリの利点と、特に静的ファクトリ メソッドの利点については認識しています。しかし、ハッキングを受け入れられるようにするために、ここで何が得られるのでしょうか?

4

2 に答える 2

3

このクラスの要点はStructuredArray、いつの日か、コンポーネント オブジェクトを含む配列全体を 1 つの長いメモリ ブロックとして割り当てる組み込み実装に置き換えることができるということです。 この場合、オブジェクトのサイズは要素の数と要素のクラスによって異なります

StructuredArrayパブリック コンストラクターがあれば、 と書くことができますx = new StructuredArray<>(StructuredArray.class, MyElement.class, length)bytecodeでは、これがnewオブジェクトを割り当てる命令になり、次にオブジェクトのコンストラクターを呼び出す の命令になることを除いて、これは問題を提示していないようです。invokespecial

オブジェクトのサイズはコンストラクターのパラメーター (要素のクラスと長さ) に依存するため、オブジェクトを割り当てる必要がありますnewが、オブジェクトを割り当てることができません。これらは、しばらくしてから続くコンストラクター呼び出しまで渡されません。

このような問題を回避する方法はありますが、それらはすべてちょっとひどいものです。構造を静的ファクトリ メソッドにカプセル化する方がはるかに理にかなっています。なぜなら、その new StructuredArray...場合newStructuredArray.そのような指示はあり得ないからです*。

後で JVM が、連続した配列を割り当てる静的ファクトリの組み込み実装を提供したい場合でも、問題ありません。ファクトリ メソッドの呼び出しで必要なすべての情報を取得します。

NB* - はい、わかりました。技術的には と書くことができnew StructuredArray...ますが、それはあなたにとって有用なオブジェクトにはなりません。

于 2016-07-22T01:47:13.263 に答える
2

セマンティクスAPI ドキュメントを調べてみると、これは主にセマンティクスの問題であることがわかりました。また、Fluent API を提供します。また、プレゼンテーションの結論のスライドに進むと、セマンティクスの箇条書きが最初に来ることに気付くはずです (ソース コードの URL を数えない場合)。

通常の配列を選択した場合。それらは、次の明確なセマンティクスを示します。

  • 配列のタイプ
  • 配列の長さ
  • 要素のタイプ

結果として

配列を操作する統一モデルがあります。API は非常に明確です。配列を操作する 10 通りの方法はありません。Java 言語開発者にとって、この API のクリーンさは非常に重要であると私は信じています。非構築可能性を強制することで、暗黙のうちに、彼らが望む方法で API を使用するよう強制しています。

工事

StructuredArray は本質的に配列でもあるためです。コンストラクターを提示すると、StructuredArray の Concrete 実装を使用することがすぐに強制されます。これにより、この統一されたモデルを導入する問題が自動的に作成されます

これが、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 がいくつかのことを強制していることです。

  1. すべてのクライアント クラスが具体的な実装ではなく、「StructuredArray」で動作するように強制しています。
  2. StructuredArray は基本的に不変です。
  3. 不変性とは、長さの厳密な表記法があることを意味します。
  4. 構造化配列には要素のソースがあります。一度消費したものは廃棄することができます。
  5. また、通常の配列と同様に、構造化配列には要素の TYPE という概念があります。

セマンティクスには非常に強力な表記法があり、著者はコーディングが正確にどのように行われるかについて優れたヒントを与えてくれていると思います。

構造化配列のもう 1 つの興味深い機能は、コンストラクターを渡す機能です。ここでも、インターフェースと 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)

コンストラクターからは、次の 3 つのことがわかります。 - 配列クラス - 要素の型 - 長さ

構造化配列がサポートする構造をさらに観察すると、次のようになります。

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)
于 2016-07-21T20:49:02.407 に答える