import java.util.*;

class G31 {
	
  public static void m1(){
    List<String>[] lsa = new List<String>[10];      // Compilation error
    Object o = lsa;
    Object[] oa = (Object[]) o;
    List<Integer> li = new ArrayList<Integer>();
    li.add(new Integer(3));
    oa[1] = li;                  // Unsound, but passes run time store check 
    String s = lsa[1].get(0);    // Run-time error: ClassCastException.
  }

  public static void m2(){
    List<?>[] lsa = new List<?>[10];    // array of unknown
    Object o = lsa;
    Object[] oa = (Object[]) o;
    List<Integer> li = new ArrayList<Integer>();
    li.add(new Integer(3));
    oa[1] = li;                         // correct 
    String s = (String) lsa[1].get(0);  // run-time error, but cast is explicit
  }

  public static void m3(){
    List<String>[] lsa = (List<String>[]) new List<?>[10]; // unchecked warning
    Object o = lsa;
    Object[] oa = (Object[]) o;
    List<Integer> li = new ArrayList<Integer>();
    li.add(new Integer(3));
    oa[1] = li;                         // correct 
    String s = lsa[1].get(0);           // run-time error, but we were warned
  }

  public static <T> T[] makeArray( int length ){ return new T[length]; }

  public static class Stack<E> {
    private E[] data;
    private int sp = 0;
    public Stack( int capacity ){
      data = new E[capacity];          // compilation error
    }
    public void push( E e ) throws StackException {
      if( sp < data.length ){
        data[sp] = e;
        sp++;
      } else throw new StackException();
    }
    public E pop( E e ) throws StackException {
      if( sp > 0 ){
        sp--;
        return data[sp];
      } else throw new StackException();
    }
    public int size(){ return sp; }
    public int capacity(){ return data.length; }
    public boolean isEmpty(){ return sp==0; }
    public boolean isFull(){ return sp==data.length; }
  }
  public static class StackException extends Exception {}
  
}