Genericsの直訳は『総称文』です。汎用的に利用されるコードを書く時に、 < と、 > 中に総称的名前を書き、 その名前を利用したプログラムを作ります。
そしてそれを利用する時、総称的名前具体的名前を指定して使う形態です。
そこからGenericsの名前が付いたのでしょう。 (Java2 SDK 1.5のバージョンから使える機能です。)

Genericsが使われる前の問題点と、基本的な使い方

Objectクラスの変数は、全てのスーパークラスなので、任意のオブジェクトを管理でき、 それを利用するアルゴリズムなどがたくさん用意されました。
それらのアルゴリズムは、対応するインターフェイスを使って作られています。
それらのアルゴリズムを利用する場合は、まずインターフェイスを実装(implements)したクラスを作ります
そうすれば、作ったクラスのオブジェクトを指定することで、それらアルゴリズムを利用できます。 それらアルゴリズムは、インターフェイスを利用して作られたプログラムだからです。

それらアルゴリズムは、汎用に使えるということでObjectクラスの変数を利用します。 Objectは、実際に使う時に目的のクラスにキャストして使います。 しかし、間違えたキャストに対してコンパイルチェックができないという問題が生じます

たぶんコンパイルエラーが起きる時、参照されるオブジェクトが使えないことを見抜けない人が多く、 強制的にキャストでコンパイルエラーに対応したもの、 見当違いの箇所で起きる実行エラーに対処できないプログラマが多かったのでしょう。
そこで、Java JDK1.5から 作る方利用する方に、 Generics と呼ぶ新しいカラクリを作りました。
これは、極力実行エラーを起こさずに、コンパイルエラーで対応できる仕組みと言えます。

以前に利用したComparableインターフェイスと、それをimplemetsしたRecord2で説明します。

package java.lang;
public interface Comparable {
    int compareTo(Object o);// 実装クラスのオブジェクトのある情報と oを比較
}
public class Record2 implements Comparable 
{
	・・・・・・省略・・・・
	//java.lang.Comparableインターフェイスのオーバーライドメソッド
	public int compareTo(Object obj)
	{
		Record2 rec = (Record2) obj;      
		String s = rec.sho;//商品コード文字列

		//Stringの比較メソッドを利用した比較
		return this.sho.compareTo(s);
	}
	・・・・・・省略・・・・
}
	public static void main(String[] arg) {
		Record2 []a = new Record2[] { new Record2("A10", 10), new Record3("B20", 20, 200), };
		Record2 key = new Record2("A10", 0);
		Comparable rec = a[0];
		int val = rec.compareTo("A10");//比較
		・・・・・・省略・・・・
	}