import java.util.*;


// javac -source 1.5 Generics.java
// Will compile with warnings
// javac -source 1.5 -Xlint Generics.java
// Generics allows you to have type safe collections
// Generics is a compile time feature and not runtime so at runtime there is type erasure

public class Generics
{

  public static void generics()
  {
	LinkedList fooList = new LinkedList();
	fooList.add(new Integer(1));  // lint warning about unchecked add


	LinkedList stringList = new LinkedList();
	// LinkedList is called base type
	// String is called parameter type

	// primitive generics not allowed
	//LinkedList intList = new LinkedList();
	stringList.add("foo");
	// The line below will throw compilation error
	//stringList.add(new Integer(1));

	// Old Style iterator code will give compilation error for stringList
	for (Iterator i = stringList.iterator(); i.hasNext();)
	{
	  String s = i.next();
	  System.out.println(s);
	}

	printStrings(stringList);
	oldStyle(stringList); // can still do old style

	// gives warning if compiled with -Xlint
	try
	{
	  for (Iterator i = fooList.iterator(); i.hasNext();)
	  {
		String s = i.next(); // ClasscastException at runtime
		System.out.println(s);
	  }
	}
	catch (ClassCastException e) { e.printStackTrace(); }

	LinkedList intList = new LinkedList();
	intList.add(new Integer(1));
	intList.add(2); // autoboxing does automatic conversion to primitive types

	printAny(intList);

	List intList2 = intList; // inhertiance rules are for base type and not parameter type
	// class Integer extends Number

	//Not Allowed for parameter type
	//List numberList = intList;
	// to prevent numberList.add(1.2)

	// can break type safety by casting and by reflection
	LinkedList numberList = intList;
	numberList.add(1.2); // allowed generated lint warning

	Map> map = new HashMap>();

	List objList1 = new LinkedList();
	objList1.add(1); // lint warning that collection is not type safe

	// for a collection which hold differnt objects so that you don't get lint warnings
	List objList2 = new LinkedList();

    MyList myList = new MyList();
    myList.add(101);
    System.out.println(myList.first());

    // Illegal
    //MyList2 f;

  }

  public static void printStrings(List stringList)
  {
	for (Iterator i = stringList.iterator(); i.hasNext();)
	{
	  String s = i.next();
	  System.out.println(s);
	}
  }


  // type wildcards
  // method that takes a List of any parameter type
  // can't do this as List as it won't take List
  // method is read only
  public static void printAny(List anyList)
  {
	// The line below will not compile as Java does not the type of the collection at compile time
	//anyList.add(new Integer(1));
	for (Iterator i = anyList.iterator(); i.hasNext();)
	{
	  System.out.println(i.next().toString());
	}
  }

  // restrict wildcards
  public static void printAnyNumber(List anyList)
  {
	// The line below will not compile as Java does not the type of the collection at compile time
	//anyList.add(new Integer(1));
	for (Iterator i = anyList.iterator(); i.hasNext();)
	{
	  System.out.println(i.next().toString());
	}
  }

  public static List getStringList()
  {
	LinkedList foo = new LinkedList();
	foo.add("foo");
	return foo;
  }

  public static void oldStyle(List fooList) {}

  // should work but doesnt
  //public static int staticSize(MyList list)
  //{
  //	return list.size();
  //}

  public static void main(String[] args)
  {
	generics();
  }
}

class MyList
{
  public MyList() { list = new LinkedList(); }
  public int size() { return list.size(); }
  public void add(T obj) { list.add(obj); }
  public T first() { return list.get(0); }



  private LinkedList list;

  // not allowed with statics
  // private static LinkedList list2;
}


// Restricting parameterized type to objects that are child of Number
class MyList2 extends MyList {}

    Source: geocities.com/sbdesai/sandeep

               ( geocities.com/sbdesai)