【文献】
青柳 龍也,「J2SE5解体新書 [第1回]Generics(その1)」,Java World,(株)IDGジャパン,2004年 9月 1日,第8巻,第9号,pp.114−121
(58)【調査した分野】(Int.Cl.,DB名)
1つ以上の計算装置上で実施されるコンパイラまたはプラットフォームに依存しないオブジェクト指向ランタイム環境によって、クラスファイルにおけるクラス名を識別することを含み、前記クラス名は構造記述を含み、前記構造記述は、ジェネレータ関数を識別する情報と前記ジェネレータ関数についての1つ以上のパラメータとを含み、さらに、
前記コンパイラまたは前記プラットフォームに依存しないオブジェクト指向ランタイム環境によって前記ジェネレータ関数を実行することを含み、前記実行することは、前記ジェネレータ関数に入力として前記1つ以上のパラメータを提供することを含み、さらに、
前記コンパイラまたは前記プラットフォームに依存しないオブジェクト指向ランタイム環境によって、前記クラス名に対応するクラスを生成することを含み、前記生成することは、前記実行することによる結果に少なくとも部分的に基づく、方法。
前記識別すること、前記実行すること、および前記生成することは、前記コンパイラによってコンパイル時間に行なわれ、前記クラスファイルは、プラットフォームに依存しないオブジェクト指向言語に基づく、請求項1に記載の方法。
前記識別すること、前記実行すること、および前記生成することは、プラットフォームに依存しないオブジェクト指向ランタイム環境において行なわれる、請求項1に記載の方法。
前記1つ以上のパラメータのうちの1つは別の構造記述を含み、前記別の構造記述は、別のジェネレータ関数を識別する情報と前記別のジェネレータ関数についての1つ以上の他のパラメータとを含み、前記実行することはさらに、
前記コンパイラまたは前記プラットフォームに依存しないオブジェクト指向ランタイム環境によって、前記別のジェネレータ関数を実行することを含み、前記別のジェネレータ関数を実行することは、前記1つ以上の他のパラメータを前記別のジェネレータ関数に入力として提供することを含み、さらに、
前記コンパイラまたは前記プラットフォームに依存しないオブジェクト指向ランタイム環境によって、前記別のジェネレータ関数を実行することからの結果を前記ジェネレータ関数に入力として提供することを含む、請求項1〜4のいずれか1項に記載の方法。
前記コンパイラまたは前記プラットフォームに依存しないオブジェクト指向ランタイム環境によって、別の構造記述を識別することをさらに含み、前記別の構造記述は、別のジェネレータ関数を識別する情報と前記別のジェネレータ関数についての1つ以上の他のパラメータとを含み、さらに、
前記構造記述と前記別の構造記述との比較、および前記1つ以上のパラメータと前記1つ以上の他のパラメータとの間の比較に少なくとも部分的に基づいて、前記構造記述および前記別の構造記述が2つの等価なクラスを表わすかどうかを、前記コンパイラまたは前記プラットフォームに依存しないオブジェクト指向ランタイム環境によって判定することを含む、請求項1〜6のいずれか1項に記載の方法。
前記プログラム命令は、プラットフォームに依存しないオブジェクト指向言語のためのコンパイラを実施するようにプロセッサ上で実行可能であり、前記コンパイラは、前記識別すること、前記実行すること、および前記生成することをコンパイル時間において行なうように構成される、請求項8に記載の計算装置。
前記プログラム命令は、プラットフォームに依存しないオブジェクト指向ランタイム環境を実施するように前記プロセッサ上で実行可能であり、前記識別すること、前記実行すること、および前記生成することは、前記プラットフォームに依存しないオブジェクト指向ランタイム環境のランタイムにおいて行なわれる、請求項8に記載の計算装置。
前記1つ以上のパラメータのうちの1つは別の構造記述を含み、前記別の構造記述は、別のジェネレータ関数を識別する情報と前記別のジェネレータ関数についての1つ以上の他のパラメータとを含み、前記ジェネレータ関数を実行するために、前記プログラム命令は、さらに前記プロセッサに、
前記別のジェネレータ関数を実行させ、前記別のジェネレータ関数を実行するために、前記プログラム命令は、さらに前記プロセッサに、前記1つ以上の他のパラメータを前記別のジェネレータ関数に入力として提供させ、
前記別のジェネレータ関数を実行することからの結果を前記ジェネレータ関数に入力として提供させる、請求項8〜10のいずれか1項に記載の計算装置。
【発明を実施するための形態】
【0006】
実施形態の詳細な説明
Java(登録商標)
TMプログラミング言語などのプラットフォームに依存しないオブジェクト指向言語を用いて、クラスの構造記述を用いて動的に生成されたパターンインスタンス化生成クラスの構造識別などの様々な特徴をサポートするためのソフトウェア開発に対する改良の様々な実施形態が本明細書に記載される。
【0007】
いくつかの実施形態によれば、動的に生成されたパターンインスタンス化クラスの構造識別は、ランタイム環境においてクラスが記述されるやり方を拡張するように、構造記述を用いて利用され得る。名前のみによってクラスを記述し、その名前を用いてそのクラスを(たとえばデスク上のクラスファイルに)見つける代わりに、クラスを、バイトコードジェネレータ関数といくつかの静的引数との組合せと称してもよい。換言すると、いくつかの実施形態では、クラスは、ジェネレータ関数を指定する構造記述(たとえば、「TからUへの機能」、「Tのアレイ」、「TおよびUのTuple」、「インターフェイスIのためのリモートプロキシ」など)と、場合によってはそのジェネレータ関数への1つ以上のパラメータとによって記述され得る。構造記述は、いくつかの実施形態では、クラス名が用いられる事実上いずれの状況についてもクラス名と考えられ得る(たとえば、クラス名として用いられ得る)。
【0008】
たとえば、クラスについての構造記述は、(名前、またはそれを実施するクラスもしくはメソッドへの参照のいずれかによる)パターンへの参照と、パターンのインスタンス化へのパラメータとを含み得る。いくつかの実施形態では、構造記述は、ジェネレータ関数を示す情報と、そのジェネレータ関数への1つ以上のパラメータとを含み得る。いくつかの実施形態では、2つの構造参照は、それらが同じパターンおよびパラメータを有する場合は同じクラス(または同じクラスへの参照)と考えられ得る。したがって、いくつかの実施形態では、クラスは、それぞれのクラス名を用いてクラスが従来から比較されているのと同じようにそれぞれの構造記述を用いて比較され得る。実際、いくつかの実施形態では、クラスの構造記述はクラスの名前と考えられてもよく、クラスの名前の代わりに使用されてもよく、したがって構造記述であり得るそれらのクラス名を用いて、クラスを比較してもよい。
【0009】
いくつかの実施形態では、クラスの構造記述において識別されるジェネレータ関数は、2つのクラスの比較に関与し得る。たとえば、ジェネレータ関数は、2つのインスタンス化が同じであるかどうかをジェネレータ関数が判定することを可能にし得るように利用(たとえば実行)され得る。したがって、いくつかの実施形態では、ジェネレータ関数は、「私は彼と同じインスタンス化であるか」という判断に関係するように構成され得る。なぜなら、インスタンス化へのパラメータが可換(たとえば、複数のインターフェイスのためのダイナミックプロキシ)であり得る場合もあれば、そうでない場合もあるからである。クラスの構造記述は、いくつかの実施形態に従って、純粋に名前だけのVM(たとえば、クラス名として構造記述をサポートするように構成されていないVM)においてクラス名が他の方法で出現することができるあらゆる場所に出現し得る。たとえば、クラスの構造記述は、引数型、戻り値型、フィールドタイプ、スーパータイプ、instanceofもしくはキャスト演算子のオペランドとして、またはそれらの代わりに、クラス名が用いられ得る概ねあらゆる場所に出現し得る。
【0010】
以下の詳細な説明では、請求項に記載の主題の十分な理解をもたらすために多くの具体的な詳細について記載する。しかしながら、請求項に記載の主題はこれらの具体的な詳細なしに実施され得ることが当業者によって理解されるであろう。他のインスタンスでは、方法、装置またはシステムは、当業者によって知られているため、請求項に記載の主題を不明瞭にしないために以下では詳細に説明しない。
【0011】
いくつかの実施形態および例示的な図面の例として本明細書に様々な実施形態を記載するが、当業者は、記載されている実施形態または図面に実施形態は限定されないと認識するであろう。図面およびそれについての詳細な説明は、開示されている特定の形態に実施形態を限定するものとは意図されておらず、逆に、開示の精神および範囲内にある変更、均等物および代替案をすべて包含する意図であることが理解されるべきである。本明細書で用いられるいずれの標題も体系化するためのものにすぎず、説明の範囲を限定するために用いられることを目的としていない。本願の全体にわたって用いられる限りにおいて、「may」という単語は、義務的な意味(つまり、しなければならないという意味)ではなく、任意の意味(つまり、可能性を有するという意味)で用いられる。同様に、「include」、「including」および「includes」という単語は、含むが限定されないことを意味する。
【0012】
以下の詳細な説明のいくつかの部分は、特定の装置または専用計算装置もしくはプラットフォームのメモリ内に格納されたバイナリデジタル信号に対する動作のアルゴリズムまたは記号表現によって表される。この特定の明細書のコンテキストでは、特定の装置などの用語は、プログラムソフトウェアからの命令に従って特定の機能を行なうようにプログラミングされた場合の汎用コンピュータを含む。アルゴリズム記述または記号表現は、信号処理において当業者によって用いられる技術、または彼らの作業の趣旨を他の当業者に伝えるための関連技術の例である。アルゴリズムは、本明細書では、かつ一般には、所望の結果に至るセルフコンシステントな一連の動作または同様の信号処理であると考えられる。このコンテキストにおいて、動作または処理は、物理量の物理的な操作を伴う。典型的には、必ずしもそうではないが、そのような量は、格納されるか、転送されるか、組合せられるか、比較されるか、または他の方法で操作されることが可能な電気または磁気信号の形態を取り得る。主として通常の用法の理由から、ビット、データ、値、要素、シンボル、文字、用語、数字、数詞などの信号を参照することが場合によっては好都合であることが分かっている。しかしながら、これらまたは同様の用語のすべては適切な物理量と関連付けられるべきであり、便宜的なラベルに過ぎないと理解されるべきである。特に別記しない限り、以下の検討から明らかなように、本明細書の全体にわたって、「処理する」、「計算する」、「算出する」、「判定する」などといった用語を利用した検討は、専用計算機または同様の専用電子計算装置などの特定の装置の行為または処理を指すと認識される。本明細書のコンテキストでは、したがって、専用計算機または同様の専用電子計算装置は、専用計算機または同様の専用電子計算装置のメモリ、レジスタ、もしくは他の情報記憶装置、伝送装置、または表示装置内の物理的、電子的、または磁気的な量として典型的に表される信号を操作するかまたは変換することが可能である。
【0013】
本明細書に記載される方法および/または特徴は、様々な実施形態に係る、(たとえば)Java仮想マシン(JVM)において動的に導出されたクラスを記述するためのベースサポート、言語レベルの概念をJVMが実行することができるバイトコードに翻訳するためのJavaコンパイラにおける翻訳メカニズム、および以前は表現することができなかったものを表現するためにJava言語で明らかにされる特徴を含むような言語開発の様々な局面を包含し得る。本明細書に記載される方法、技術、特徴、および/または改良の様々な実施形態は、Javaプログラミング言語に関して、かつ/またはJavaプログラミング言語を用いたソフトウェア開発の特徴を用いて、検討される。しかしながら、本明細書に記載される方法、技術、特徴、および他の改良は、様々な実施形態に従って、C、C++、C#、Scala(登録商標)、Pythonなどの他のプログラミング言語と使用されてもよい。
【0014】
図1を参照して、様々な実施形態に従って、高水準なプラットフォームに依存しないオブジェクト指向言語で指定されるコンピュータプログラム、ならびに本明細書に記載されるクラスの構造記述に関する様々な方法、特徴、および改良をコンパイルし実行するためのワークフローを例示する。例示の目的で、以下の説明の大部分はJava
TMプログラミング言語を用いるコンテキストで提供される。しかしながら、記載される技術は、名前で記述されるユーザ定義クラスをサポートする事実上いずれのプログラミング言語と用いられてもよい。一般に、クラスは、特殊な型のプログラミングオブジェクトを作成するために、データ、変数、関数、メソッド、および/または他の属性をメンバーとして含んでもよく、かつ定義、ブループリント、またはテンプレートを表わすユーザ定義型またはデータ構造と考えられ得る。クラスは、メンバー関数およびメソッドのためのデータメンバーおよび実装例に初期値を提供し得る。クラスは、しばしばライブラリに含まれる。ライブラリは、ソフトウェアプログラムまたはアプリケーションによって使用されるリソースの集合と考えられ得る。ライブラリは、いくつかの実施形態に従って、限定はされないがデータ、ドキュメンテーション、クラス、サブルーチン、および/または型指定を含む様々な種類のリソースのうちのいずれかを含み得る。ライブラリは、2つ以上のアプリケーションによって(場合によっては同時に)利用されるように体系化されてもよく、アプリケーションが同じ挙動を実施(または再実施)しなくてもよいようにリソースを提供することによって再利用性を促進し得る。
【0015】
例示される実施形態によれば、ソースコードファイル110などの、コンピュータプログラムのためのソースコードをコンパイラ120などのコンパイラが受信すると、ワークフローが開始し得る。様々な実施形態において、ソースコードファイル110は、Java
TMおよび/または他の言語などの、様々な高水準の、かつ/またはプラットフォームに依存しないオブジェクト指向プログラミング言語で指定され得る。たとえば、ソースコードは、Java
TMが用いられている実施形態において一組の.javaファイルとして提供され得る。いくつかの実施形態では、ソースコードファイル110は、1つ以上の低水準な、かつ/または中間言語(たとえばアセンブリ)を含み得る言語の組合せを用いて指定され得る。いくつかの実施形態では、ソースコードの少なくとも一部は初めにPythonまたはRuby(登録商標)などの動的型付き高水準言語で書かれ得るが、他の実施形態では、ソースコードのすべてがJava
TMなどの静的型付き言語であり得る。
【0016】
コンパイラ120は、ソースコードファイル110を分析して、図示の実施形態においてクラスファイル130(たとえば、Java
TMの場合は.classファイルまたは.jarファイル)などの実行可能なバージョンのプログラムまたはバイトコードファイルを生成し得る。異なる種類の実行可能なコードフォーマットを様々な実施形態において使用してもよい。たとえば、バイナリ機械語をバイトコードの代わりに使用してもよい。いくつかのシナリオでは、クラスファイル130における実行可能コードの一部はバイトコードであり得るが、他のものは固有のバイナリ機械語であり得る。
【0017】
プログラムソースコードファイル110をクラスファイル130にコンパイルすることの一部として、コンパイラ120は、いくつかの実施形態に従って、一連の解析動作を行ない、クラスの構造記述を適用するかまたは実施するように、実行可能なバージョンを生成する前に様々な中間データ構造を生成し得る。たとえば、コンパイラは、クラスファイル130を作成する際、クラスの1つ以上の構造記述を追加するかまたは含み得る。上記のように、構造記述は、ジェネレータ関数を示す情報とそのジェネレータ関数への1つ以上のパラメータとを含み得る。
【0018】
図1に例示されるように、クラスファイル130は、実行プラットフォーム102上でコードを実行する、仮想化ランタイム環境140などの実行環境に送られ、それによって様々な出力データおよび/または挙動を作成し得る。仮想化ランタイム環境140は、ひいては、様々な実施形態に従って、クラスローダ150、メモリマネージャ160、(たとえば実行可能コードの有効性をチェックするための)バイトコードベリファイヤ170、および/またはインタープリタおよび/またはジャストインタイム(JIT)コンパイラ180などの多くの異なるコンポーネントを含み得る。JITコンパイラは、いくつかの実施形態では、バイトコードの一部またはすべて(たとえばバイトコードのよく使用される部分)をプラットフォーム固有のマシンコードに翻訳して、プログラム実行のパフォーマンスを向上させる役割を担い得る。仮想化ランタイム環境140は、いくつかの実施形態では、多くのアプリケーションプログラミングインターフェイス(API)ライブラリ190を実施するためのコードも含み得る。仮想化ランタイム環境140は、いくつかの実施形態では、オペレーティングシステム192などの下位レベルソフトウェア上で動作し得る。
【0019】
異なる実施形態では、コンパイルされたコードの実行の結果として生成される出力または挙動は、様々なレベルのシステムメモリ(たとえばメモリ内オブジェクトおよび/またはデータ構造)、永続ストレージ(たとえばファイルシステム上のファイル)などに格納されたデータを含み得る。挙動は、出力をスクリーン上に表示する、ネットワークによってメッセージを送信する、かつ/または他の方法で様々なユーザおよび/またはコンポーネントと相互作用するなどの様々なプログラム機能性も含み得る。
【0020】
いくつかの実施形態では、仮想化ランタイム環境140は、コンパイラ120によって生成されたクラスファイル130を用いたクラスの構造記述を実施し得る。いくつかの実施形態によれば、クラスの構造記述を実施する仮想化ランタイム環境140は、クラスをローディングする際、(構造記述へのパラメータと共に)クラスファイル130からの構造記述を使用してもよく、(構造記述において指定された)ジェネレータ関数を(同じく構造記述に指定されている)パラメータに適用した結果であり得る新しいクラスを生成してもよい。
【0021】
動的に生成されたパターンインスタンス化の構造識別
いくつかの実施形態によれば、動的に生成されたパターンインスタンス化クラスの構造識別は、ランタイム環境においてクラスが記述されるやり方を拡張するように構造記述を用いて利用され得る。名前によってのみクラスを記述し、その名前を用いてクラスを(たとえばディスク上のクラスファイルにおいて)見つける代わりに、クラスを、コードジェネレータ関数といくつかの静的引数との組合せと称してもよい。換言すると、いくつかの実施形態では、ジェネレータ関数を指定する構造記述と、場合によってはそのジェネレータ関数への1つ以上のパラメータとによってクラスを記述してもよい。構造記述は、いくつかの実施形態では、クラス名が用いられる事実上いずれの状況についてもクラス名と考えられ得る(たとえばクラス名として使用され得る)。
【0022】
したがって、いくつかの実施形態によれば、ソフトウェアシステム(たとえばコンパイラおよび/または仮想ランタイム環境)を増強して、クラスを生成するためのレシピまたは公式を符号化し得る構造記述を用いることによってクラスを記述することを可能にし得る。構造記述は、(たとえば、名前による、またはそれを実施するクラスもしくは方法の参照による)パターンの参照などのジェネレータ関数の識別と、あるとすればジェネレータ関数についてのパラメータ(たとえばパターンのインスタンス化へのパラメータ)とを含み得る。
【0023】
このように、いくつかの実施形態に従って、何らかのジェネレータ関数をいくつかの引数に適用した結果であるクラスは、ジェネレータ関数を指定する構造記述と(場合によっては)1つ以上の引数とを用いて参照され得る。たとえば、特殊化の場合には、そのジェネレータ関数は、特殊化されるべきクラスとその特殊化引数とを引数として取り得る。したがって、コンスタントプールにおける「合成クラス」はTuple(たとえば、generator=JavaGenericSpecializer, args=ArrayList, int)により参照され得る。いくつかの実施形態によれば、合成クラスについての構造記述は、ソースコード、クラスファイル、および/または生成コード内で利用され得る。
【0024】
いくつかの実施形態では、合成クラスについてのコードの生成は、クラスが解消される時などにランタイム環境によって行なわれる。その結果、そのクラスが参照される時はいつでも合成クラスがコードに出現し得る。構造記述は、様々な実施形態に従って、ほぼいずれの機械的な変換またはクラスの生成にも用いられ得る。構造記述が使用され得る状況のいくつかは(とりわけ)、
・特殊化(たとえば、List<T>をT=intに特殊化すること)
・インターフェイスIについてのダイナミックプロキシ
・その方法はIの背景にあるインスタンスに権限を委任し得る、インターフェイスIについての転送プロキシ
・指定されたコンポーネント型を有するタプル型
・指定された引数を有する関数型および戻り値型
を含み得る。
【0025】
ソースコード(たとえば手書きコード)は、「パラメータA,BおよびCでXYZパターンをインスタンス化する」形態の記述から機械的に(たとえば自動的に)生成されることができていた既存パターンのインスタンス化を含み得ることが多い。
【0026】
パターンへのパラメータは、他の型またはクラス(たとえば「Decorator around ActionListener」)であってもよく、このコードを機械的に(たとえば自動的に)生成することは、いくつかの実施形態では、パターンを手でインスタンス化するよりも単純であり、エラーを起こしにくいが、より重要なことには、断定的に結果を参照すること(「インターフェイスListについてのダイナミックプロキシ」)は、(たとえばコードを読む人に対する)読み手の明瞭性)と、(たとえば、VMまたはプラットフォームライブラリコード内の)他のコンポーネントがクラスの構造記述を吟味し、かつそのセマンティクスについての情報を判定することができることとの両方の面から、より明確である。
【0027】
クラスを記述するための基本的な方法として構造記述を用いることにより、クラスの生成が可能となり得るだけでなく、型がクラスファイルに出現する限りどこでも構造記述の使用も可能となり得る。たとえば、構造記述は、他の例の中でも、class foo extends Tuple<int, int>、instanceofテスト(たとえば特定の要素がTuple<int, int>かどうかを判定すること)を実施するため、またはTuple<int, int>にキャストするために使用され得る。したがって、VMは、従来のプログラミング言語とは対照的に、ソース言語において用いられるものと同じクラス記述を用いてもよく、ランタイムにおいて使用するための、名前が支離滅裂なコードを生成しつつ、ソース言語において1つの表現を用いてもよい。
【0028】
したがって、構造記述は、いくつかの実施形態では、クラスを記述する(かつ生成する)ための全般的なメカニズムと考えられ得る。加えて、クラス名がクラスファイルに出現し得るいずれの場所でも構造記述が使用され得るため、構造記述を用いることでランタイム環境の表現性も上昇し得る。
【0029】
いくつかの実施形態では、構造記述の使用は、ローディングされるべきクラスを記述するための間接層と考えられ得る。たとえば、ファイルシステムにおけるパスとして、またはデータベースにおけるキーとして、クラス名を用いてローディングされるべきクラスファイルを生成すると述べる代わりに、あるパラメータによる特定のジェネレータの実行に起因するクラスとして、または特定のやり方でのクラスの変形に起因するクラスとして(構造記述を用いて)クラスが記述される。
【0030】
したがって、(たとえばクラス名によって)ファイルシステム内で検索することでどのようにクラスを見つけるかを記述することによってクラスを識別するのではなく、公式(またはレシピ)を用いて、次いで公式のインスタンス化を用いてどのようにクラスを生成するかという記述によってクラスが識別される。いくつかの実施形態では、特定の公式(たとえばジェネレータ関数)と、その公式へのパラメータとの組合せが、クラスファイルにおいてクラスの実際の名前の代わりに用いられる。したがって、クラスを名前によって参照することができることに加え、クラスは公式またはレシピによって(たとえば構造記述を用いることによって)も参照され得る。換言すると、クラスは、名前でまたは構造的に識別され、かつ/または参照され得る。
【0031】
構造記述によって識別されたクラスがローディングされる時に、クラスが構造記述によって識別されるという事実が認識されてもよく、次いで、クラスを生成するために特定のジェネレータ関数が用いられてもよい。いくつかの実施形態では、クラスの構造記述は、そのクラスについての唯一の(たとえば正式な)クラス名と考えられ(かつ用いられ)得る。したがって、2つの異なるクラスにおける2つの構造記述が両方ともListについてダイナミックプロキシを指定する場合、コンパイラまたは仮想化ランタイム環境は、2つの構造記述が同じクラスについてのものであると認識し得、構造記述の一方を用いて先に生成されたクラスを再使用することになる。換言すると、クラスの構造記述は、いくつかの実施形態に従って、他の構造記述と比較され得るクラスの具体的な記述と考えられ得る。
【0032】
たとえば、動的なクラスは、入力として0以上のパラメータを取り得る1つのジェネレータ関数(または公式/レシピ)であり得る。いくつかの実施形態では、ジェネレータ関数への1つのパラメータは、新しいクラスを生成するためにコードが適合される(たとえばジェネレータ関数によって変形される)ことになる既存クラスのクラス名であり得る。加えて、いくつかの実施形態では、クラスの構造記述は別の構造記述についての引数として機能することができ、したがってジェネレータ関数に引数として送られてもよい。一般にジェネレータ関数は、様々な実施形態に従って、限定はしないがメソッド名、値、数字、定数、クラス名、および/またはクラスについての構造記述を含む様々な種類のパラメータを取り得る。ジェネレータ関数への入力引数の厳密な性質および型は、ジェネレータ関数ごとに、かつ実施形態ごとに変動し得る。
【0033】
したがって、いくつかの実施形態では、構造記述は、必ずしも記述の個々の部分の特定の意味ではなく、それらの構造に基づいていくつかのコンポーネントによって用いられ得る。たとえば、一実施形態では、コンパイラは、言語のランタイムライブラリの一部として特定のジェネレータ関数を発することによって、構造記述に特定の意味を与え得る(たとえば、構造記述は特定のクラスを生成するためのものであることをコンパイラは知っている)。しかし他のコンポーネントは、記述の個々の部分の特定の意味の知識を必要とすることなく、単に構造記述により作動する。たとえば、ある状況において、かついくつかの実施形態に従って、仮想化ランタイム環境の1つ以上のコンポーネントは、生成されているクラスの詳細に関して特に知識がなくても、構造記述によって指定されるジェネレータ関数を特定し実行するように構成され得る。
【0034】
したがって、実施形態では、構造記述の使用は、高水準言語のユーザがランタイム表現とは何かを知る必要なしに、コンパイラがソース構造体を合理的なランタイム表現にマッピングすることを可能にする仮想化ランタイム環境によって提供される特徴と考えられ得る(たとえば、プログラマはランタイム表現ではなく言語の型システムだけを見ればよい)。
【0035】
いくつかの実施形態では、構造記述の使用は、ユーザのプログラムの表現がランタイム環境が効率的に管理することができるものにマッピングすることができるようにコンパイラを展開するために用いられる特徴のツールボックスの一部と考えられ得る。構造記述の実施は、複数の関係者および複数の間接層を伴い得る。たとえば、ランタイム環境は、プログラマが高水準言語でコードを書くと、場合によっては良好な性能および予測可能な挙動を保証するように簡単な描写的マッピングがあり得るように、構造記述を利用して言語コンパイラに自然な表現を提供し得る。
【0036】
いくつかの実施形態では、仮想化ランタイム環境は動的にリンクされてもよい。したがって、特定のクラスXからのコードが別のクラスYの方法を呼び出す場合、コンパイラはクラスYについてのクラスファイルを検索し、クラスYへの通話を生成し、Xについてのクラスファイルに署名を入れてもよい。しかしながら、コードが適切に実行するために、ランタイムにおいて、同じクラスYは、コンパイラが使用したのと同じ署名を有することが必要となる。同様に、構造記述を利用する際、(たとえば構造記述を用いて)まずクラスが生成され、次いでコンパイル時間において検査され得る。次いで、いくつかの実施形態では、構造記述がコードに保持されつつ、生成されたクラスが廃棄され得る。コードが適切に実行するために、ランタイムにおいて、同じジェネレータ関数が、互換性のあるクラスについて同じ署名を生成することが必要となる。したがって、構造記述を実施する際、コンパイラは、クラス全体を生成する必要はなく、構造記述だけを用いることによってクラスを発行することが可能であり得る。
【0037】
いくつかの実施形態では、言語ランタイムライブラリの一部などの、1つ以上のあらかじめ生成されたジェネレータ関数が利用可能であり得る。1つのJavaベースの例では、いくつかの実施形態に従って、Tupleを生成するために構造記述が用いられてもよく、したがって適切なランタイムライブラリにおいてTupleジェネレータ関数が提供されてもよい。いくつかの実施形態では、ランタイムライブラリは、Tupleクラスが生成される必要がある場合に用いられ得るTupleジェネレータクラスを含み得る。そのような例では、Javaコンパイラは、Tupleジェネレータ関数が何を生成しようとしているかを正確に知り得る。しかし他の実施形態では、クラスを生成する(次いで、生成されたクラスを標準として用いる)ために構造記述で指定された特定のジェネレータ関数をどのように呼び出すか以外のことについて(何らかの詳細を)特定のコンパイラが知らなくてもよい別の言語のランタイムの一部である他のジェネレータ関数があり得る。
【0038】
同様に、いくつかの実施形態に従って、言語は構造記述を用いて特殊化を実施してもよく、したがって、スペシャライザジェネレータ関数(および/またはスペシャライザジェネレータクラス)がランタイムライブラリ内に設けられてもよい。
【0039】
いくつかの実施形態では、仮想化ランタイム環境140などのランタイム環境は、ジェネレータ関数のセマンティクスまたは用いられている個々のレシピ、公式もしくはパターンに関して何も知らなくてもよい。その代わり、ランタイム環境は、クラスがローディングされる必要がある時には、構造記述によって指定されたジェネレータ関数をコードジェネレータとして単に用いればよい。たとえば、一実施形態では、ランタイム環境はまずコードジェネレータ(たとえばジェネレータ関数)を実行してクラスを作成し、次いでクラスローダ150などのクラスローダを用いてそのクラスをローディングし得る。他の実施形態では、ランタイム環境は、クラスローダに依拠して、ジェネレータ関数を実行し、かつ結果として生じるクラスをローディングし得る。
【0040】
したがって、いくつかの実施形態では、構造記述の使用は、ランタイム環境が、特定のクラスおよび/またはジェネレータ関数の詳細を理解することなく、どのようにクラスを生成するかのみを恐らく理解している状態での(たとえば構造記述に基づく)クラスの生成に関するコンパイラとランタイムライブラリとの一致と考えられ得る。
【0041】
Listについてのダイナミックプロキシを実施するコードを作成するかまたは把握することよりも、「Listについてのダイナミックプロキシ」と述べ理解する方が容易であり得るため、(たとえばパターンのパラメータ化されたインスタンス化などの)構造記述としてクラスを表わすことは、より高い表現性およびリーダビリティをプログラマに提示し得る。さらに、その同じパターンを手動でインスタンス化するよりもよりコンパクトで読取り可能であるパターンを用いるためのコードであるだけではなく、変化に対してよりロバストであり得る。たとえば、クラスCについてのプロキシが手書きされ、新しいメソッドを有するようにCがその後修正された場合、手書きのプロキシはそのメソッドを含まないであろう。しかしながら、ランタイムにおいて目標クラスを検討することによってどのメソッドをプロキシするかを選択するランタイムに生成されたプロキシは、クラスCと同期したままであろう。
【0042】
図2は、一実施形態に係る、本明細書に記載されるクラスの構造記述を例示する論理ブロック図である。上記のように、クラス名は構造記述200などの構造記述によって表わされ得る。たとえば、仮想化ランタイム環境140などのランタイム環境は、いくつかの実施形態においてクラスを生成するためのレシピの符号化と考えられ得る構造記述200によってクラスが記述されることを可能にするように構成され得る。たとえば、
図2に示されるように、構造記述200は、ジェネレータ関数識別子210とジェネレータ関数についての1つ以上のパラメータ220とを含み得る。
【0043】
ジェネレータ関数識別子210は、異なる実施形態によれば、ジェネレータ関数を識別する様々なやり方のうちのいずれかを表わし得る。たとえば、一実施形態では、ジェネレータ関数識別子210は、パラメータ220を用いて特定型のクラスを生成するように構成されたジェネレータ関数の名前を表わし得る。別の実施形態では、ジェネレータ関数識別子210は、特定のジェネレータ関数を実施するように構成されたクラスまたはメソッドへの参照を表わし得る。したがって、ジェネレータ関数識別子210によって識別されたジェネレータ関数は、様々な実施形態によれば、論理ジェネレータ関数または実際のプログラム関数(またはメソッド)を表わし得る。
【0044】
たとえば、一実施形態では、構造記述200は、(たとえば、名前による、またはそれを実施するクラスもしくはメソッドへの参照による)パターンへの参照と、パターンのインスタンス化へのパラメータとを含み得る。仮想化ランタイム環境は、クラスを名前で(たとえばクラス名によって)参照し得る。たとえば、同じ名前を有する場合、2つのクラス参照は同じと考えられ得る。いくつかの実施形態では、クラスは、パターンのインスタンス化に基づいて生成され得る。そのようなインスタンス化は、様々な種類の引数を取り得る。
【0045】
たとえば、「Xインターフェイスのための転送プロキシ」または「Yインターフェイスのためのファクトリ」は各々、パターンのインスタンス化に基づいて生成されることになるクラスを表わし得る。例示的な一実施形態に従って、「Xインターフェイスのための転送プロキシ」のパターン例のインスタンス化に基づいて生成されることになるクラスについての構造記述200は、転送プロキシジェネレータ関数を識別するジェネレータ関数識別子210を含んでもよく、特定のXインターフェイスを表わすパラメータ220を含んでもよい。同様に、「Yインターフェイスのためのファクトリ」のパターン例のインスタンス化に基づいて生成されることになるクラスについての構造記述200は、例示的な一実施形態によれば、ファクトリジェネレータ関数を識別するジェネレータ関数識別子210を含んでもよく、特定のYインターフェイスを表わすパラメータ220を含んでもよい。
【0046】
上記のように、いくつかの実施形態では、ジェネレータ関数(たとえばパターンのインスタンス化)に基づいてクラスが生成され得る。
図3は、一実施形態に係る、構造記述に基づくクラスの生成を例示する論理ブロック図である。
図3に例示されるように、仮想化ランタイム環境140などの仮想化ランタイム環境(またはクラスローダ150などの、仮想化ランタイム環境140のコンポーネント)は、クラスファイル300における構造記述310などの構造記述に遭遇(たとえば識別、発見など)し得る。たとえば、仮想化ランタイム環境140は、クラスファイル300からのコードを実行していてもよいし、クラスファイル300のコード内の構造記述310を識別してもよい。
【0047】
構造記述310によって記述されるクラスを生成するために、仮想化ランタイム環境140は、ジェネレータ関数330などの適切なジェネレータ関数を識別し、特定し得る。いくつかの実施形態では、仮想化ランタイム環境140は、上述のジェネレータ関数識別子などの構造記述310内の情報に基づいてジェネレータ関数330を識別し得る。ジェネレータ関数は、いくつかの実施形態によれば、仮想化ランタイム環境140にアクセス可能なランタイムライブラリ内などの様々な場所のいずれかに配置され得る。いくつかの実施形態では、ジェネレータ関数330は、構造記述に基づいてクラスを生成するように構成されたメソッドまたはクラスを表わし得る。
【0048】
仮想化ランタイム環境140は、構造記述310に対応するクラスを生成するためにジェネレータ関数330を実行するように構成されてもよく、構造記述310からジェネレータ関数330に1つ以上のパラメータを(たとえば実行されたメソッドへの引数として)送ってもよい。一実施形態では、ジェネレータ関数330に個々のパラメータを送るのではなく、仮想化ランタイム環境140は、構造記述310を引数としてジェネレータ関数330に送るように構成されてもよい。ジェネレータ関数330は、その場合、構造記述310に対応する(たとえば構造記述310によって記述される)クラスを生成する際に構造記述310の情報を利用し得る。たとえば、ジェネレータ関数330は、構造記述310からの1つ以上のパラメータを使用してもよい。
【0049】
ジェネレータ関数330は、様々な実施形態によれば、構造記述310によって記述されるクラスに対応する、または該クラスを生成するのに使用可能な、ジェネレータ関数結果340などの結果または出力を生成し得る。たとえば、一実施形態では、ジェネレータ関数結果340は、クラスを規定するかまたは宣言するソースコードであってもよく、ソースコードは、仮想化ランタイム環境140によってコンパイルされ、かつ/または他の方法で用いられるのに好適であり得る。別の実施形態では、ジェネレータ関数結果340は、構造記述310によって記述されるクラスについての、すでにコンパイルされたコード(たとえばバイトコード)を含み得る。たとえば、構造記述310は、別のすでにコンパイルされたクラスからのバイトコードの単純な変換によって生成され得るクラスを記述してもよく、したがってジェネレータ関数330は、クラスの実行可能なバイトコード形式を仮想化ランタイム環境140に提供することが可能であり得る。
【0050】
仮想化ランタイム環境140は、異なる実施形態に従って、様々なやり方のいずれかでジェネレータ関数結果340を利用するように構成されてもよい。たとえば、一実施形態では、仮想化ランタイム環境140は、生成されたクラスを(たとえばジェネレータ関数結果340に基づいて)メモリまたはディスクのいずれかのクラスファイルに格納するように構成されてもよい。
【0051】
仮想化ランタイム環境によって行なわれると上記したが、様々な実施形態によれば、ソフトウェア開発および/または実行環境の他のコンポーネントによってクラスが生成されてもよい。たとえば、一実施形態では、コンパイラは、
図4に関してより詳細に以下で述べられるように、構造記述に基づいてクラスを生成するように構成されてもよい。
【0052】
図4は、本明細書に記載されるように、クラスの構造記述に基づいてクラスを生成するための方法の一実施形態を例示するフローチャートである。ブロック400に示されるように、構造記述はクラスファイルにおいて識別されてもよく、構造記述は、ジェネレータ関数を識別する情報とジェネレータ関数についての1つ以上のパラメータとを含んでもよい。たとえば、一実施形態では、コンパイラ120は、両方とも
図3に関して上記したクラスファイル300の構造記述310などの構造記述によって記述されたクラスを、識別するように構成されてもよい。
図3は仮想化ランタイム環境140によるクラスの生成を例示したが、いくつかの実施形態では、コンパイラ120も仮想化ランタイム環境140を参照して上記したようにクラス生成を行なうように構成されてもよい。一般に、ソフトウェア開発および/または実行環境の様々なコンポーネントのうちのいずれも、本明細書に記載されるように、かつ様々な実施形態に従って、クラスの構造記述を利用するように構成され得る。
【0053】
図4に戻り、ブロック400に示されるように、一実施形態では、コンパイラ120は、クラスファイル300内の構造記述310を識別し得る。構造記述310は、ジェネレータ関数を識別する情報とジェネレータ関数についての1つ以上のパラメータとを含み得る。たとえば、それぞれ転送プロキシクラスおよびインターフェイスファクトリクラスを生成するように構成された2つのジェネレータ関数は各々、実施形態例によれば、結果として生じるクラスと共に用いられることになる特定型のインターフェイスを表わす1つ以上の引数を取り得る。
【0054】
いくつかの実施形態では、コンパイラ120はクラス名として構造記述を利用するように構成されてもよく、構造記述によって記述される(たとえばクラスファイル中の)クラスを識別した後、ブロック410によって例示されるように、構造記述において指定されたジェネレータ関数を実行し、入力引数として1つ以上のパラメータをジェネレータ関数に提供し得る。たとえば、コンパイラ120は、ジェネレータ関数330を実行し、かつ引数として1つ以上のパラメータをジェネレータ関数330に送るように構成され得る。一般に、異なる実施形態に従って構造記述を実施する一部としてジェネレータ関数を実行する場合には、入力パラメータを提供する任意の好適な方法を利用してもよい。
【0055】
いくつかの実施形態では、ジェネレータ関数に個々のパラメータを提供するのではなく、構造記述自体をジェネレータ関数に入力として提供してもよく、ジェネレータ関数はそこから個々のパラメータを取得してもよい。たとえば、一例によれば、ジェネレータ関数330を実行する際、コンパイラ120は、構造記述310を入力引数として提供してもよい。
【0056】
識別されたジェネレータ関数を実行した後、コンパイラは、ブロック420に示されるように、ジェネレータ関数からの結果(たとえば出力)に少なくとも部分的に基づいて、構造記述によって記述されたクラスに対応するクラスを生成するように構成されてもよい。たとえば、ジェネレータ関数330は、様々な実施形態によれば、クラスを作成するのに使用可能な情報を含むジェネレータ関数結果340を生成してもよく、コンパイラ120は、ジェネレータ関数結果340を得て、ジェネレータ関数結果340をクラスファイル350に保存することなどによって、対応するクラスを作成してもよい。
【0057】
上記のように、構造記述の一使用例は、特定のデータ型について特殊化された(たとえばパラメータ化された)クラスを生成することである。たとえば、ジェネレータ関数は、特殊化されることになるクラスおよびその特殊化引数を引数として取り得る。たとえば、以下のBoxクラス例は、構造記述を用いてT=intにより特殊化され得る。
【0059】
コンパイラ(および/または仮想化ランタイム環境のコンポーネント)は、BoxクラスがT=intについて特殊化されるべきであることを示す構造記述を含むソースコードに遭遇し得る、たとえばソースコード例によって表わされ得る:
【0061】
コンパイラが上記のソースコードに遭遇すると、特殊化ジェネレータ関数を指定する構造記述を用いてBoxクラスおよび型Integer(たとえばint)をパラメータとして用いてT=intについてBoxクラスが特殊化されるべきであることを認識し得る。したがって、コンパイラは、Boxクラス(場合によっては一例としてクラス名「Box」)を指定するパラメータとデータ型intとを(引数として)送るスペシャライザジェネレータ関数を特定し実行し得る。応答して、スペシャライザジェネレータ関数は、以下の例などにおいてT=intについて特殊化されたBoxクラスを実施するソースコードを生成し得る:
【0063】
次いで、コンパイラは、ジェネレータ関数(たとえば生成クラスソースコード)の結果を得て、必要とされるように使用し得る(たとえば、クラスファイルなどにそれをコンパイラおよび/または保存する)。
【0064】
同様に、コンパイラ120は、以下のコード例によって表されるようなTupleジェネレータ関数および2つのパラメータを指定する構造記述にソースコード内で遭遇し得る:
【0066】
上記の例では、構造記述は、カッコ内の2つのパラメータの型(たとえばT1およびT2)と共にキーワード「Tuple」を含む。構造記述との遭遇に応じて、コンパイラは、入力パラメータとして2つの型を送るTupleジェネレータ関数を実行し得る。ジェネレータ関数の結果は、2つの型についてTupleクラスを実施する追加的なソースコードを含み得る。たとえば、上記の例におけるT1が整数型を表わし、上記の例におけるT2が文字列型を表わす場合、Tupleジェネレータ関数は、以下のソースコード例のように、整数および文字列を有するTupleを実施するためのソースコードを生成し得る:
【0068】
上記の特殊化された例と比較して、Tuple例は、入力として供給されたクラスを単純に特殊化するのではなく、ジェネレータ関数がどのように新しいソースコードを生成し得るかを例示する。しかし他の実施形態では、上記のTuple例はスペシャライザジェネレータ関数の特殊なケースとして実施されてもよい。
【0069】
ジェネレータ関数によるコード出力(たとえばジェネレータ関数の結果)は次いでコンパイラによって利用されてもよい(たとえばクラスファイル内などにコンパイルされ、かつ/または保存され得る)。いくつかの実施形態では、構造記述の使用によって生成される結果として生じるクラスは、デベロッパーには見られない(または利用可能ではない)かもしれない。その代り、システムの内部にあり、構造記述の代わりに用いられると考えられ得る。たとえば、上記のTuple例では、デベロッパーはTuple<T1, T2>クラス(またはオブジェクト)を使用し参照してもよいが、構造記述の使用に応じて生成された内部のTuple$98456表現は見てはならない。
【0070】
コンパイラに関して上記したが、
図4に例示される方法は、ソフトウェア開発または実行環境の様々なコンポーネントのいずれかによって、たとえば仮想化ランタイム環境、および/または仮想化ランタイム環境内のクラスローダによって行なわれてもよい。
【0071】
Javaベース仮想マシン(VM)などの仮想化ランタイム環境は、クラスを名前で(たとえば名前によって)参照し得る。従来から、クラスは以下の例の部分的なコンスタントプールダンプのように名前のみによって参照され得る:
コンスタントプール:
【0073】
上記の例では、「Class」定数は、クラス名を記述する文字列定数を参照する。バイトコードにおける様々な用途(スーパークラス名、呼び出されるべきメソッドを所有するクラスの名前、およびinstanceofオペランド))は、このやり方でクラスを名前で参照し得る。
【0074】
同じ名前を有する場合、2つのクラス参照は同じと考えられ得る。これは、各クラスが固有で、既知の、安定した名前を有すると想定し得るし、各クラスが(手または機械によって)静的に生成され、ファイルシステムに格納されることも通常は必要とし得るが、特定のジェネレータ関数(たとえば特定の生成、変換、および/またはパターン)を特定の入力もしくはパラメータに適用するインスタンスとしてよりよく記述(および比較)され得る多くのクラスがある。
【0075】
したがって、いくつかの実施形態では、(たとえばクラスファイル中の)クラスは、その引数に適用されると、クラスおよび(場合によっては)所望のインスタンス化を記述する一組の引数を生成するジェネレータ関数を含む構造記述を用いて記述され得る。それらの名前によって同一性が比較されるのではなく、そのような構造クラスは、同じジェネレータ関数および引数を有することによって同一性が比較されてもよい。
【0076】
いくつかの実施形態では、結果として生じるクラスを生成するためにジェネレータ関数を呼び出すことなく構造記述を比較してもよい。その代わり、構造記述は、それらの個々の要素の比較などによって構造的に比較されてもよい。たとえば、Listクラス上のダイナミックプロキシジェネレータを用いて1つの構造記述が指定し、Listクラス上のダイナミックプロキシジェネレータを用いて別のものが指定する場合、それらは、指定されたジェネレータ関数をまず比較し、それらが同じであれば、それぞれのジェネレータ関数に送られている特定のパラメータを比較することによって、比較され得る。
【0077】
加えて、いくつかの実施形態によれば、2つのクラスはそれぞれの構造記述に基づいて比較されてもよい。
図5は、本明細書に記載されるように、2つのクラスをそれらの構造記述に基づいて比較するための方法の一実施形態を例示するフローチャートである。たとえば、2つの構造記述(たとえばパターンへの2つの構造参照)は、それらが同じジェネレータ関数およびパラメータ(たとえば同じパターンおよびパラメータ)を利用する場合、同じクラスである(または表わす)と考えられ得る。
【0078】
ブロック500に示されるように2つのクラスをそれらの構造記述に基づいて比較することは、ブロック510に示されるように2つのクラスについてのジェネレータ関数を比較することを含み得る。たとえば、一実施形態では、コンパイラ120は、ジェネレータ関数を識別する構造記述の情報を比較することによって、2つのクラスのジェネレータ関数を比較するように構成され得る。たとえば、一実施形態によれば、2つの構造記述がジェネレータ関数の名前を含み、両者が同じ名前を含む場合、2つの構造記述は同じジェネレータ関数を識別すると考えられ得る。
【0079】
決定ブロック520の肯定的な出力によって示されるように、2つのジェネレータ関数が同じである(たとえば、両方の構造記述が同じジェネレータ関数を識別する)場合は、ブロック530に示されるように、ジェネレータ関数についてのパラメータが比較され得る。たとえば、いくつかの実施形態によれば、2つのクラスは、それらが異なるパラメータを同じジェネレータ関数に送ることに基づく場合は、異なると考えられ得る。たとえば、両方ともTupleジェネレータ関数に基づく2つのクラスは、それらが異なるパラメータをジェネレータ関数に送る(たとえば一方が2つの整数を指定し、他方はパラメータとして文字列および整数を指定する)場合は、異なると考えられ得る。
【0080】
決定ブロック540の肯定的な出力によって示されるように、2つの構造記述によって指定されるパラメータが同じである場合は、ブロック550でのように、2つの構造記述は同じクラスを表わすと考えられ得る。しかし、決定ブロック520の否定的な出力によって示されるようにジェネレータ関数が同じでないか、または決定ブロック540の否定的な出力によって示されるようにパラメータが一致しない場合、ブロック560でのように、2つの構造記述は2つの異なるクラスを表わすと考えられ得る。
【0081】
いくつかの実施形態によれば、構造記述の個々の部分(たとえばジェネレータ関数識別子、パラメータ)が比較されてもよいが、結果として生じるクラスは生成されなくてもよい。いくつかの実施形態では、2つの構造記述の比較の一部としてなされる個々の比較は、物事を名前で(たとえば原文どおりに、名前によって)比較することを包含し得るが、他の実施形態では含まなくてもよい。たとえば、一実施形態では、ジェネレータ関数は構造記述内の名前によって指定されてもよく、したがって、ジェネレータ関数識別子は、(たとえば、ジェネレータ関数識別名であるため)名前で比較され得る。他の実施形態では、構造記述の個々の部分は他のやり方で(たとえば、数、参照などを比較することによって)比較され得る。
【0082】
いくつかの実施形態では、2つの構造記述の個々の部分の比較は、構造記述の個々の一部をプログラマ/デベロッパーに比較させるのではなく、ライブラリ機能および/またはライブラリクラスによってのみ行なわれ得る。
【0083】
いくつかの実施形態では、ジェネレータ関数は、それらの構造記述を用いたクラスの比較に関係することが可能とされ得る。たとえば、構造記述において示されたジェネレータ関数は、2つのクラスが同じかどうかの判断に関係することが可能とされ得る。したがって、いくつかの実施形態において、それらの構造記述に基づいて2つのクラスを比較する場合、コンパイラ120は、比較されているクラスについての構造記述の1つにおいて識別されるジェネレータ関数に関連付けられるメソッドを呼び出すように構成され得る。コンパイラは、比較されている構造記述のうち1つ以上を呼び出されたメソッドに送り得る。次いでメソッドは、(たとえば、構造記述の情報を比較するなどによって)構造記述が同じクラスを表わすか否かを判定し得る。
【0084】
たとえば、いくつかの場合には、ジェネレータ関数への(たとえばパターンのインスタンス化への)パラメータは可換(たとえば複数のインターフェイスのためのダイナミックプロキシ)であり得るが、他の場合にはそうではないかもしれない。(たとえばパターンインスタンス化の)そのような構造記述は、他の方法でクラス名が出現することができるいかなる場所に出現してもよい。たとえば、クラスの構造記述は、引数型、戻り値型、フィールドタイプ、スーパータイプ、instanceofもしくはキャスト演算子のオペランド、またはクラス名が用いられ得る事実上あらゆる場所として、またはその一部として出現し得る。
【0085】
いくつかの実施形態では、構造記述の使用は再帰的であり得る。たとえば、クラスを生成する際にジェネレータ関数への入力として用いられることになるパラメータのうちの1つ以上は、クラスについての構造記述であり得る。
図6は、一実施形態に係る、再帰的に用いられる構造記述を例示する論理図である。
図2に示されるように、上記の構造記述200などの構造記述は、ジェネレータ関数識別子および識別されたジェネレータ関数についての1つ以上のパラメータを含んでもよい。いくつかの実施形態では、ジェネレータ関数へのパラメータのうちの1つ以上はクラスであり得、それらのクラスは、構造記述によって表わされ(たとえば記述され)得る。したがって、構造記述200のパラメータ220は、1つの例示的な実施形態によれば、構造記述600であり得る(または表し得る)。構造記述600は、ジェネレータ関数識別子610と1つ以上のパラメータとを含み得る。
【0086】
ジェネレータ関数識別子610は、異なる実施形態によれば、ジェネレータ関数識別子210によって識別されたものと同じかまたは異なるジェネレータ関数を識別し得る。したがって、いくつかの実施形態では、ジェネレータ関数(またはジェネレータ関数を表わすクラス)は再帰的に実行されるように構成され得る。
【0087】
構造記述200によって表されるクラスを生成する際、コンパイラ120は、まず構造記述600によって表されるクラスを生成し、次いでそのクラスを構造記述200についてのジェネレータ関数に入力として送るように構成され得る。したがって、いくつかの実施形態では、コンパイラ120は、生成されることになるクラスをそれらのうちいずれかが表わしているかどうかを判定するために、構造記述のすべてのパラメータを調べるように構成され得る。他の実施形態では、ジェネレータ関数自体が、入力パラメータが構造記述であり得ると認識するように構成されてもよく、さらに、その構造記述に基づいてクラスを生成し、かつ生成したクラスをそれ自身のクラスを生成するための入力として使用するように構成されてもよい。
【0088】
図6に例示されるような一連の構造記述は、複数の反復層を含んでもよい。たとえば、構造記述600のパラメータ620は、ジェネレータ関数識別子650およびパラメータ660を含み得る構造記述640であり得る(または参照し得る)。ジェネレータ関数識別子650は、ジェネレータ関数識別子210によって識別されるのと同じジェネレータ関数を表わしてもよいし、ジェネレータ関数識別子610によって識別されるのと同じジェネレータ関数を表わしてもよいし、異なるジェネレータ関数を表わしてもよい。同様に、構造記述600のパラメータ630は、ジェネレータ関数識別子680およびパラメータ690を含み得る構造記述670であり得る(または参照し得る)。
【0089】
さらに、構造記述を用いたクラスの比較は、様々な実施形態によれば、複数の構造記述の層を介した反復を伴い得る。たとえば、構造記述の1つ以上によって指定された個々のパラメータは、それら自体が構造記述であり得る。したがって、比較は、個々のパラメータ自体が構造記述でなくなるまで複数の構造記述の層を介した反復を必要とし得る。比較されている2つの当初の構造記述が各反復層において同じジェネレータ関数とパラメータとを指定する構造記述の同じ層を含む場合は、比較されている2つの当初の構造記述(と、したがって2つの当初のクラスと)は同じと考えられ得る。
【0090】
一般に、構造記述は、ある種類から別の種類への、事実上いずれの機械的な変換にも用いられ得る。たとえば、様々な実施形態によれば、構造記述は、T=intについてのジェネリッククラスList<T>を特殊化し、1つ以上のインターフェイスのためのダイナミックプロキシを実施し、1つ以上のインターフェイスのためのプロキシの転送を実施し、所与のコンポーネント型を有するTupleを表わすクラスを実施するため、かつ所与の引数および戻り値型についての構造機能型を表わすクラスを実施するために利用され得る。
【0091】
様々な実施形態に係る構造記述を用いるのに好適な状況の例は、次のものを含み得る:
包括的な特殊化
構造記述を用いるのに好適な変形の1つの例は、包括的な特殊化を実施することを含み得る。構造記述を用いて特殊化を実施する際、ジェネレータ関数は、(部分的にまたは全体的に)特殊化されることになるクラスおよび特殊化に用いられることになる特殊化された型の引数を引数として取り得る。たとえば、List<T>がT=intにより特殊化されると指定する構造記述は、特殊化ルールに従って注釈された署名および命令を変更し、ほかのすべては変更しないことによってクラスList<T>を変形した結果であるクラスを生成し得る。
【0092】
したがって、ランタイムライブラリによって提供される1つのジェネレータ関数は、その引数が特殊化されるべきクラスおよびタイプ引数の特殊化を指定し得るスペシャライザ関数であり得る。たとえば、intのArrayListが生成されることになる場合、構造記述は、ArrayListおよびintを引数としてスペシャライザジェネレータ関数を実行したことに起因するダイナミッククラスの生成を指定する。いくつかの実施形態では、スペシャライザジェネレータ関数は、特殊化されるべきクラスのクラスファイルを読出し、かつ新しいクラスファイルを生成し得る。古いクラスファイルの構造を用いて、スペシャライザジェネレータ関数は、いくつかの実施形態に従って、メソッド署名、フィールドなどの型を特殊化するようにobjectの使用をintに置換しつつ、新しいクラスファイルにいくつかのアイテムを直接送ってもよい。
【0093】
インターフェイスのためのダイナミックプロキシ
構造記述を用いるのに好適な変形の別の例は、いくつかの実施形態によれば、1つ以上のインターフェイスのためのダイナミックプロキシを実施することを含み得る。たとえば、ジェネレータ関数は、プロキシへの一組のインターフェイスを引数として取ってもよく、それらのインターフェイスをすべて実施するクラスを生成してもよく、そのメソッドは、結果として生じるクラスのコンストラクタに送られる呼出しハンドラに急送される。したがって、一実施形態によれば、ダイナミックプロキシの生成を指定する構造記述は、ダイナミックプロキシジェネレータ関数の識別を含んでもよく、パラメータとして1つ以上のインターフェイス型を指定してもよい。
【0094】
たとえば、デベロッパーは、クラスのgetメソッドが呼び出されると、getメソッドへの呼出のどこでどのパラメータが用いられるかを示すハンドラメソッドも呼び出されるように(たとえばgetメソッド呼出が遮断され得るように)、Listインターフェイスを実施するクラスのインスタンスを実施したい場合がある。換言すると、デベロッパーは、Listインターフェイスのためのダイナミックプロキシを実施したい場合がある。
【0095】
ダイナミックプロキシを実施するために、構造記述は、ダイナミックプロキシジェネレータ関数を実行する際にパラメータとして使用されることになるインターフェイス(たとえばList interface)を指定し得る。
【0096】
インターフェイスのためのプロキシの転送
同様に、いくつかの実施形態によれば、構造記述を用いて1つ以上のインターフェイスのための転送プロキシを実施してもよい。たとえば、ジェネレータ関数はプロキシへの一組のインターフェイスをパラメータとして取ってもよく、(たとえば、Corba、またはEnterprise Java Beans、またはRemote Method Invocationなどとの使用のために)ネットワークまたはリモートプロキシクラスを実施するようにこれらのインターフェイスをすべて実施するクラスを生成してもよい。
【0097】
ダイナミックプロキシに関して上記したように呼出しハンドラに急送するのではなく、メソッド呼出は、これらのインターフェイスを実施し、かつ結果として生じるクラスのコンストラクタに提供され得る背景にあるオブジェクトに転送されてもよい。したがって、構造記述は、転送プロキシジェネレータ関数および1つ以上のインターフェイスをパラメータとして指定し得る。
【0098】
Tuple型
構造記述を用いるのに好適な変形の別の例は、いくつかの実施形態によれば、指定されたコンポーネント型を有するタプル型を含み得る。たとえば、フィールドの型を引数として取り、その特定のTupleを表わすクラスを出力し、指定された型の要素を有するTupleジェネレータ関数が提供され得る。
【0099】
たとえば、デベロッパーは、以下の例などの2つのデータ型T1およびT2についてTupleを実施するソースコードを書込んでもよい。
【0101】
コンパイラは、Tupleジェネレータ関数および型T1およびT2をパラメータとして指定する構造記述を用いてもよい。たとえば、構造記述は、2つのパラメータの型(たとえばT1およびT2)と共に、特定のジェネレータ関数(たとえば「Tuple」)を識別するキーワードを含んでもよい。ランタイムにおいて、構造記述が用いられると、ランタイム環境は、2つのデータ型を送るジェネレータ関数を引数として識別し、特定し、実行し得る。Tupleジェネレータ関数は次いで、以下のコード例のように、2つの指定されたデータ型を用いて、Tupleクラスを規定するバイトコードを出力し得る:
【0103】
プロキシの縮小
構造記述を用いるのに好適な変形の別の例は、縮小プロキシを含み得る。たとえば、クラスCはインターフェイスIを実施してもよい。クラスCは何らかの他のメソッドに送られ得るが、インターフェイスIのメソッドのみが可視であることが望ましい場合がある(つまりCが何らかの他の型にダウンキャストされることが望ましくない場合がある)。
【0104】
従来は、以下のコード例のように、手動アダプタが書込まれるであろう:
【0106】
いくつかの実施形態では、引数としてクラスIを取り、IAdapterを生成するジェネレータ関数が書込まれてもよい。このメカニズムによって、各Iについてアダプタを手で書込む必要性がなくなり得、その代わり、構造記述を用いて必要に応じて生成され得る。たとえば、構造記述は、縮小プロキシジェネレータ関数およびクラスIをパラメータとして指定し得る。実行されると、生成された縮小プロキシは、上記の例のようにIAdapterクラスを生成し得る。
【0107】
コンパイル時間における生成されたクラスの内観
加えて、いくつかの実施形態では、コンパイル時間においてクラスが内観され得る。たとえば、「class Foo extends List<int>」の時、List<int>が動的に生成され、コンパイラは次いでList<int>の要素を識別するためにジェネレータを実行しなければならない場合があり、コンパイル決定を下すためにそれを使用する。同じクラスは、その後のランタイムで再度特殊化されてもよい。
【0108】
加えて、「class Foo extends List<int>」の場合/時、構造記述を用いてList<int>が実施される(たとえば、名前だけのクラスではなくパターンのインスタンス化として表される)場合、コンパイラは、いくつかの実施形態では、スーパークラスの構造および要素を知る必要があり得る。たとえば、コンパイラ120は、その場合、対応するジェネレータ関数を実行してList<int>クラスを生成し、それに対して反射的に内観し、必要とされるデータを収集し得る。特殊化されたクラスは次いで、実際に用いられるランタイムにおいて再生成され得る。
【0109】
生成されたクラスに対する反映
生成されたクラスは、「見苦しい」(たとえば複雑な)名前を有する(または名前を有さない)場合がある。しかしながら、ユーザはこのクラスに対して反映させたい場合がある。したがって、いくつかの実施形態では、生成された(たとえば複雑な、または「見苦しい」)名前を、コンパイル型の静的な型システムの反映図に再度接続してもよい。さらに、クラスがたとえばGenerated$List$$23$T=intなどの、より複雑な名前を実際に有する場合であっても、生成されたクラスの名前の人間が読取り可能な(たとえば人にやさしい)記述が復元され得る。
【0110】
いくつかの実施形態では、構造記述の実施は、生成されたクラスを、それを作成するために用いられた特定のジェネレータ(たとえば特定の変形、レシピ、公式など)に接続し返す方法を提供し得る。したがって、いくつかの実施形態では、構造記述は、人間が読取り可能なテキスト形式で、用いられた特定のジェネレータをレンダリングするやり方を提供し得る。加えて、いくつかの実施形態では、構造記述の実施は、特定の構造記述を、当初用いられた言語の型システムにマッピングし返すためのメカニズムも提供し得る。たとえば、ランタイム環境がクラスを参照するための低水準メカニズムとして構造記述を提供する一方、高水準言語(たとえばJava)は、型システムを提供してもよく、様々な種類の高水準言語を表わすやり方として構造記述を用いてもよい。
【0111】
反映メカニズムを利用する場合、高水準言語のあらゆる種類を、(ランタイム環境によって用いられる型システムとは異なり得る)高水準言語の型システムにマッピングするやり方で反射層に記述可能とすることが望ましい場合がある。したがって、いくつかの実施形態では、構造記述の型が(たとえば高水準言語の)当初の型システムに接続し返され得るように、言語の固有の型システムの、構造記述への言語固有のマッピングが逆転されてもよい。
【0112】
上記の検討は、クラス、メソッドなどになされる手作業による変更について記載しているが、両者とも上記したコンパイラ120などのコンパイラ、または仮想化ランタイム環境140などの仮想化ランタイム環境は、手作業で行なわれるものとして上記した特徴を、理解し、分析し、または他の方法で処理するように構成されてもよい。たとえば、クラスおよびメソッドの手作業による改良に関する上記の節は、クラスまたは方法を手作業で追加するかまたは修正することを指し得るが、コンパイラまたは仮想は、たとえばクラスを適切に特殊化するように、手作業で修正されたコード(またはバイトコード)を受付けて処理するように構成されてもよい。一般に、コードに対する手作業の修正を用いた様々な方法、特徴および/または改良が本明細書に記載され得るが、そのような記載は説明を簡単にするためであり、そのような方法、特徴および/または改良の実施は、コンパイラおよび/または仮想マシンも伴い得る。
【0113】
主として静的なだけの型を参照して上記したが、本明細書に記載した方法、特徴および/または改良は、静的なだけの型には限定されない。いくつかの実施形態では、本明細書に記載した方法、特徴および/または改良は、動的な型に適用されてもよい。たとえば、
【0115】
などの(たとえば、リストの型パラメータが型境界を侵害した場合、何らかの種のランタイム例外が適用されるであろう)チェックされたが不十分に特殊化された式が本明細書に記載される方法、特徴および/または改良によって行なわれてもよい。
【0116】
少なくともいくつかの実施形態では、本明細書に記載される技術の1つ以上の一部分またはすべてを実施するコンピュータシステムは、1つ以上のコンピュータ読取可能媒体を含むかまたはアクセスするように構成される汎用コンピュータシステムを含み得る。
図7は、本明細書に記載される方法、特徴および改良を実施するのに好適なそのような汎用の計算装置3000を例示する。例示される実施形態では、計算装置3000は、入力/出力(I/O)インターフェイス3030を介してシステムメモリ3020に結合された1つ以上のプロセッサ3010を含む。計算装置3000は、I/Oインターフェイス3030に結合されたネットワークインターフェイス3040をさらに含む。
【0117】
様々な実施形態において、計算装置3000は、1つのプロセッサ3010を含むユニプロセッサシステム、またはいくつかのプロセッサ3010(たとえば2つ、4つ、8つ、または別の好適な数)を含むマルチプロセッサシステムであり得る。プロセッサ3010は、命令を実行することが可能な任意の好適なプロセッサを含み得る。たとえば、様々な実施形態では、プロセッサ3010は、x86、PowerPC、SPARC、もしくはMIPS ISAなどの様々な命令セットアーキテクチャ(ISA)のうちいずれか、または任意の他の好適なISAを実施する、汎用または埋込みプロセッサであり得る。マルチプロセッサシステムでは、プロセッサ3010の各々は、必ずではないが一般に、同じISAを実施し得る。
【0118】
システムメモリ3020は、プロセッサ3010によってアクセス可能なプログラム命令およびデータを格納するように構成され得る。様々な実施形態では、システムメモリ3020は、静的ランダムアクセス記憶装置(SRAM)、シンクロナスダイナミックRAM(SDRAM)、不揮発性/フラッシュ型メモリ、または任意の他の種類のメモリなどの任意の好適なメモリ技術を用いて実装され得る。例示される実施形態では、上記したそれらの方法、技術、およびデータなどの1つ以上の所望の機能を実施するプログラム命令およびデータは、コード(つまりプログラム命令)3025およびデータ3026としてシステムメモリ3020内に格納されるように示される。たとえば、メモリ3020ならびにコード3025およびデータ3026は、一実施形態では、上記のコンパイラ120および/または仮想化ランタイム環境140を実施するためのプログラム命令およびデータを格納し得る。
【0119】
様々な実施形態では、コンパイラ120および/または仮想化ランタイム環境140(および/またはその任意の個々のサブモジュール)は各々、様々なプログラミング言語または方法のいずれかで実施され得る。たとえば、一実施形態において、コンパイラ120および/または仮想化ランタイム環境140はC、C++、アセンブリ、JAVA、または他の汎用プログラミング言語のいずれかで書かれてもよいが、別の実施形態では、それらの1つ以上は、異なる、より特殊化されたプログラミング言語で書かれてもよい。また、いくつかの実施形態では、コンパイラ120および/または仮想化ランタイム環境140(および/またはその様々なサブモジュール)は、同じプログラミング言語を用いて実施されなくてもよい。
【0120】
一実施形態では、I/Oインターフェイス3030は、プロセッサ3010、システムメモリ3020、およびネットワークインターフェイス3040または他の周辺インターフェイスを含む装置内の任意の周辺機器の間のI/Oトラフィックを調整するように構成され得る。いくつかの実施形態では、I/Oインターフェイス3030は、1つのコンポーネント(たとえばシステムメモリ3020)からのデータ信号を別のコンポーネント(たとえばプロセッサ3010)による使用に好適なフォーマットに変換するために、任意の必要なプロトコル、タイミングまたは他のデータ変換を行ってもよい。いくつかの実施形態では、I/Oインターフェイス3030は、たとえば周辺コンポーネント相互接続(PCI)バス規格またはユニバーサル・シリアル・バス(USB)規格の変形例などの様々な種類の周辺バスによって取付けられた装置のためのサポートを含み得る。また、いくつかの実施形態では、システムメモリ3020へのインターフェイスなどのI/Oインターフェイス3030の機能性のうちのいくつかまたはすべてがプロセッサ3010に直接組込まれてもよい。
【0121】
ネットワークインターフェイス3040は、計算装置3000とネットワーク3050に取付けられた他の装置3060との間でデータが交換されることを可能にするように構成され得る。様々な実施形態では、ネットワークインターフェイス3040は、たとえばイーサネット(登録商標)ネットワークの種類などの任意の好適な有線または無線の一般的なデータネットワークによる通信をサポートし得る。
【0122】
いくつかの実施形態では、システムメモリ3020は、対応する方法および装置の実施形態を実施するために
図1〜
図6を参照して上記したようにプログラム命令およびデータを格納するように構成されたコンピュータ読取可能(たとえばコンピュータアクセス可能な)媒体の一実施形態であり得る。しかし、他の実施形態では、プログラム命令および/またはデータは、異なる種類のコンピュータ読取可能媒体上で受信されても、送信されても、格納されてもよい。概して言えば、コンピュータ読取可能媒体は、磁気または光媒体、たとえばI/Oインターフェイス3030を介して計算装置3000に結合されたディスクまたはDVD/CDなどの非一時的な記憶媒体を含み得る。非一時的なコンピュータ読取可能記憶媒体は、システムメモリ3020または別の種類のメモリとして計算装置3000のいくつかの実施形態において含まれ得るRAM(たとえばSDRAM、DDR SDRAM、RDRAM、SRAMなど)、ROMなどといった任意の揮発性または不揮発性媒体も含み得る。
【0123】
さらに、コンピュータ読取可能媒体は、ネットワークインターフェイス3040によって実施され得るような、ネットワークおよび/または無線リンクなどの通信媒体によって伝達される電気、電磁気、またはデジタル信号などの伝送媒体または信号を含み得る。
図7に例示されるような複数の計算装置の部分またはすべてを用いて、様々な実施形態において記載した機能性を実施してもよい。たとえば、、様々な異なる装置およびサーバ上で動作するソフトウェアコンポーネントが協働して機能性を提供してもよい。いくつかの実施形態では、記載した機能性の部分は、汎用コンピュータシステムを用いて実施されることに加えて、またはその代わりに、記憶装置、ネットワークデバイスまたは専用計算機システムを用いて実施されてもよい。本明細書で用いられる限りにおいて、「計算装置」という用語は少なくともすべてのこれらの種類の装置を指し、これらの種類の装置に限定されない。
【0124】
様々な実施形態は、コンピュータ読取可能媒体についての前述の記載に従って実施される命令および/またはデータを受信すること、送信すること、または格納することをさらに含み得る。概して言えば、コンピュータ読取可能媒体は、磁気または光学媒体、たとえばディスクまたはDVD/CD−ROM、RAM(たとえばSDRAM、DDR、RDRAM、SRAMなど)、ROMなどといった揮発性または不揮発性媒体などの記憶媒体またはメモリ媒体を含み得る。いくつかの実施形態では、コンピュータ読取可能媒体は、ネットワークおよび/または無線リンクなどの通信媒体によって伝達される電気、電磁気、またはデジタル信号などの伝送媒体または信号も含み得る。
【0125】
図に例示され、本明細書に記載された様々な方法は、方法の典型的な実施形態を表わす。方法は、ソフトウェア、ハードウェアまたはその組合せで実施され得る。様々な方法において、ステップの順序を変更してもよく、様々な要素を追加、並べ替え、組合せ、省略、修正などしてもよい。様々なステップを自動的に(たとえばユーザ入力によって直接促されることなく)、かつ/またはプログラムによって(たとえばプログラム命令に従って)行なわれてもよい。
【0126】
具体的な実施形態を参照して、かつそれらのコンテキストにおいて様々なシステムおよび方法を本明細書に記載したが、これらの実施形態は例示的なものであり、開示の範囲はこれらの具体的な実施形態に限定されないことが理解されるであろう。多くの変形、修正、追加、および改善が可能である。たとえば、説明において識別されたブロックおよび論理単位は、記載した実施形態を理解するためのものであり、開示を限定することは意図していない。たとえば、コンパイラ120によって行なわれると本明細書で記載された作用、プロセス、方法、タスク、または機能は、いくつかの実施形態では仮想化ランタイム環境140によって行われてもよいし、逆もまた同様である。加えて、機能性は、本明細書に記載したかまたは異なる用語で記載したシステムおよび方法の様々な実現において違ったやり方でブロックに分離されても組合せられてもよい。
【0127】
これらの実施形態は、例示的であって限定しないことを意図している。したがって、単一のインスタンスとして本明細書に記載したコンポーネントに複数のインスタンスを提供してもよい。様々なコンポーネント、動作、およびデータストアの間の境界線はやや恣意的であり、特定の動作は具体的な例示的な構成のコンテキストにおいて例示される。機能性の他の割当てが想定され、後続する例の範囲内にあり得る。最後に、典型的な構成における個別部品として提示された構造および機能性は、組合せられた構造またはコンポーネントとして実施され得る。
【0128】
上記の実施形態は詳細に記載したが、上記の開示が十分に認識されれば、多くの変形および修正が明らかとなるであろう。そのような変形および修正をすべて包含するように以下の請求項が理解されることが意図される。