【C++言語vsJava言語】C++テンプレートとJavaジェネリックの違い
C++のテンプレート(template)機能は、ある意味コンパイラ言語の
限界に挑戦した機能追加だった。
クラスの雛形や関数に抽象的な型変数としてさらに一段上の抽象化を
狙ったところまでは良かった。
しかしこのテンプレートの型は基本型から何から何でも放り込んで
矛盾が生じなければ、コンパイラを通してしまう構文規格にした
ところがまずかった。
結果、コンパイラはテンプレートの抽象型に型を放り込む(具体化)
するたびに、新しい型を生成して、出力されたオブジェクトファイル
には膨大な型シンボルやコードが生成され、しかも各オブジェクト毎に
同様の型で生成されたテンプレート型コードをリンカに全てお任せる
という言わば、リンカ泣かせの言語だったのだ。
その点、JavaのジェネリックはC++で失敗した同じ轍を踏まなかった。
JavaはObject型を全てのクラスの基底クラスとして位置づけ、
ジェネリックも基本型などは許さず、全てObject型から継承された
型でなければ許さなかった。
またコンパイル時に固有の型で生成(C++でいう具体化)したとしても
それはコンパイル時の型チェックを行うという目的でのみ許可して
最終的にはObject型として生成(ジェネリック)され、固有の型で
一時的に生成された型は全て型消去(Type Erasure)して、型爆発を
防いだ点も賢い。
JavaはC++言語と同じ失敗を嫌い、用意周到にジェネリックとして
機能追加を行った。さすがはSun MicroSystems(現Oracleに買収)
と言ったところだろうか。。
蛇足だが、昨今、PythonやJavaScriptなど型を指定しないで変数を
宣言できるインタープリタ言語では、そもそも型に依存しないクラス
や関数がかけるので、そもそもC++テンプレートやJavaジェネリック
などの特殊構文はないことを付け加えておくか。。。
C++のテンプレート(template)機能は、ある意味コンパイラ言語の
限界に挑戦した機能追加だった。
クラスの雛形や関数に抽象的な型変数としてさらに一段上の抽象化を
狙ったところまでは良かった。
しかしこのテンプレートの型は基本型から何から何でも放り込んで
矛盾が生じなければ、コンパイラを通してしまう構文規格にした
ところがまずかった。
結果、コンパイラはテンプレートの抽象型に型を放り込む(具体化)
するたびに、新しい型を生成して、出力されたオブジェクトファイル
には膨大な型シンボルやコードが生成され、しかも各オブジェクト毎に
同様の型で生成されたテンプレート型コードをリンカに全てお任せる
という言わば、リンカ泣かせの言語だったのだ。
その点、JavaのジェネリックはC++で失敗した同じ轍を踏まなかった。
JavaはObject型を全てのクラスの基底クラスとして位置づけ、
ジェネリックも基本型などは許さず、全てObject型から継承された
型でなければ許さなかった。
またコンパイル時に固有の型で生成(C++でいう具体化)したとしても
それはコンパイル時の型チェックを行うという目的でのみ許可して
最終的にはObject型として生成(ジェネリック)され、固有の型で
一時的に生成された型は全て型消去(Type Erasure)して、型爆発を
防いだ点も賢い。
JavaはC++言語と同じ失敗を嫌い、用意周到にジェネリックとして
機能追加を行った。さすがはSun MicroSystems(現Oracleに買収)
と言ったところだろうか。。
蛇足だが、昨今、PythonやJavaScriptなど型を指定しないで変数を
宣言できるインタープリタ言語では、そもそも型に依存しないクラス
や関数がかけるので、そもそもC++テンプレートやJavaジェネリック
などの特殊構文はないことを付け加えておくか。。。