According to this post Java checks generics types only at run time but the same post's answer mentions that
Generics were introduced to the Java language to provide tighter type checks at compile time
I don't quite understand the answer there. Is the type check performed at compile time or at runtime?
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Address[] ad= new Address[3];
    ArrayList<Address> arr= new ArrayList<Address>();
    Employe e=new Employe(4, "harish");
    Address a = new Address();
    a.setOffice("SEX");
    ad[0]=a;
    arr.add(a);
    CopyOnWriteArrayList<Employe> c = new CopyOnWriteArrayList(arr);
    for(Employe em: c)System.out.println(e.getName());
    listimplementations v =new listimplementations();
}
From my code the collection<Address> is successfully added inside another collection<Employe> and I'm getting an error at runtime 
Exception in thread "main" java.lang.ClassCastException: collection.Address 
cannot be cast to collection.Employe
at collection.listimplementations.main(listimplementations.java:26)
only during the for loop retrieval.  I think this is because inside  CopyOnWriteArrayList uses Object Array to store elements irrespective of generics type <Employe>.
- If <Employe>is effectively erased during compilation then how do generics provide tighter type checks at compile time ?
- Why is a compilation error not thrown during compile time for adding Addresstype insideEmployetype collection?
