22

村の馬鹿になる危険を冒して、ジェネリックがジェネリックと呼ばれる理由を誰かが私に説明できますか?それらの使用法と利点は理解していますが、genericの定義が「general」であり、genericコレクションがタイプセーフである場合、なぜこれは誤った名称ではないのでしょうか。

たとえば、ArrayListは、オブジェクトであるすべてのものを保持できます。

ArrayList myObjects = new ArrayList();
myObjects.Add("one");
myObjects.Add(1);

一方、文字列型のジェネリックコレクションは文字列のみを保持できます。

var myStrings = new List<string>();
myStrings.Add("one");
myStrings.Add("1");

なぜ「ジェネリック」と呼ばれるのかよくわかりません。答えが「...クラスまたはメソッドがクライアントコードによって宣言およびインスタンス化されるまで、1つ以上の型の指定を延期するクラスおよびメソッドを設計することを可能にする」の場合。ここから、それは理にかなっていると思います。Javaがジェネリックスを導入してからプログラミングを始めたので、おそらく私はこの精神的な失墜を経験しているので、それらの前の時間を思い出せません。それでも...

どんな助けでも大歓迎です。

4

9 に答える 9

21

「ジェネリック」は実装について話している。使用するタイプごとに特定の実装を作成する代わりに、任意のタイプで機能する単一の「ジェネリック」リスト実装を作成します。

于 2008-11-21T16:01:27.697 に答える
15

このような質問に対する正しい答えは、ほとんどの場合、「ほとんどの場合、歴史的な理由」だと思います。ジェネリックスは、「スキーム」、「クラス」、「型族」、「属」、「型関数」、「静力学」、「ギリシャ語型」など、何百万ものものと呼ばれることもあります。ずっと前に誰かが「ジェネリック」という言葉を使うことに決めました、そしてそれは立ち往生しました。

Javaの意味での「ジェネリック」は、少なくとも1970年代半ばにまでさかのぼります。米国国防総省は、新しいプログラミング言語(ADAになるもの)の要件文書を磨いていました。初期のドラフト(「Woodenman」、1975年8月)は次のように述べています。

各要素タイプの定義を繰り返さずに、ジェネリックプロシージャやスタック、キューなどのデータ構造を指定できるようにするには、拡張可能な言語でコンパイル時パラメータが必要です。

これは、ドキュメントでの「一般」の唯一の使用法です。それがどのように意図されたのかは私にはわかりません。しかし、1977年7月(「Tinman」)までに、ジェネリックに関する段落全体があり、この用語は明らかに特定の何かを意味するようになりました。

12D。一般的な定義

各呼び出しで変換中にインスタンス化されるパラメーターを使用して、関数、プロシージャー、およびタイプを定義することが可能でなければなりません。このようなパラメーターは、定義された任意の識別子(変数、関数、または型のパラメーターを含む)、式、またはステートメントです。これらのパラメータは、他のすべてのパラメータと同様に、呼び出しのコンテキストで評価される必要があります。

1978年6月(「スティールマン」)までに専門用語が確立されました。この機能を明確に参照して、ドキュメントの他のセクションで「一般的」という用語の他の使用法がありました。完成した言語でgenericは、予約語でした。

これらのドキュメントの作成者はサイトにリストされており、おそらくほとんどがまだ存在しています。彼らに電話して、何を覚えているか尋ねるのはいいことです。


私が学界で見つけた「ジェネリック」の最も初期の関連する使用法は、ロビン・ミルナーの「プログラミングにおける型多型の理論」(1978)にありました(そして彼は「ジェネリック」が何を意味するのかを説明せざるを得ないと感じているので、当時、学界で一般的に使用されていました):

したがって、これは一般的なタイプのマップです。つまり、この宣言のスコープ内でマップが出現する場合は、このタイプの置換インスタンスを割り当てる必要があります。

「ジェネリック型変数」はCS用語になりました。

于 2009-11-24T23:15:31.110 に答える
4
bool Equals(int x, int y)

上記の方法は整数しか比較できないため、整数の比較に特化していると言えます。

bool Equals<T>(T x, T y);

上記のメソッドは任意のタイプの値を比較できるため、特定のタイプに特化したものではなく、汎用であると言えます。

于 2009-11-24T23:26:43.043 に答える
1

私は言語のセマンティクス(Javaではなく英語)に触れたくありません。そしてトートロジーであなたに答えるリスクがあります。ジェネリックメソッドは、あなたが言ったように、一般的な意味で使用でき、特定のタイプを持たず、一般的に使用できるため、ジェネリックと呼ばれます

于 2008-11-21T16:01:27.180 に答える
1

さて、私は完全に推測しているので、これを一粒の塩と一緒に取ってください、しかしそれは「ジェネレーティブタイプ」のろくでなしであるかもしれないのではないかと思います。

概念的には、リストをList <String>に特化すると、新しいタイプが生成されます。少なくとも、それはC ++テンプレートとC#ジェネリックで機能する方法です。

Javaでは、パラメータ化は型消去を使用してコンパイラによって破棄されるため、実際には新しい特殊な型は生成されません。

Javaはジェネレーティブタイプのジェネリック化バージョンを実装していると言えるでしょう:)


編集中:

ここに別の視点があります...

List <String>型は、「ジェネリック」型を参照するときに彼らが話しているものではありません。用語は実際にはList<T>タイプを指していると思います。これは、タイプがその一般的な形式でどのように存在するかを示しています。List <String>は、ジェネリックList<T>を特殊化したものです。

于 2008-11-21T16:04:39.390 に答える
0

彼らがそれを「タイプパラメータ」と呼んだ場合、人々はそれをタイプタイプのパラメータと混同するでしょう。

また、ArrayListは「汎用」ではありません。オブジェクトのタイプでのみ機能します。あなたがそれに何かを求めるならば、それはあなたにオブジェクト参照を与えるでしょう。これは非常に特殊な動作です。

于 2008-11-21T16:00:49.150 に答える
0

オブジェクトを受け取るクラスはジェネリックではなく、それ自体がジェネリック型である型を非常に具体的に取っています。一方、ジェネリッククラスは、特定のタイプで使用できます。

于 2008-11-21T16:02:07.587 に答える
0

同じ方法で(指定した制約内で)任意のタイプで動作できる「ジェネリック」コードを作成しているため...

よく知っている良い例は、Add演算子はほぼすべての言語です...整数、浮動小数点数、倍精度浮動小数点数、10進数、2進数、16進数を、符号付き、符号なし、ビット数に関係なく「追加」できます。 、など..。

于 2008-11-21T16:02:07.803 に答える
-1

私は「ネイティブ」の英語を話す人ではないので、間違っている可能性がありますが、「ジェネリック」のポイントは、「ジェネリックの定義」タイプですよね。

于 2008-11-21T16:01:05.497 に答える