1   /**
2    * Esimerkki dynaamisesta taulukosta Java 1.5:n geneerisyyttä
3    * ja reflektiona käyttäen niin, että voi tallentaa vain
4    * alkiota jotka toteuttavat tietyn rajapinnan ja uusi
5    * alkio luodaan lisäyksen yhteydessä.
6    * @author Vesa Lappalainen
7    * @version 1.0, 02.03.2002
8    * @version 1.1, 01.03.2005
9    */
10  
11  interface LukuRajapinta {
12    public void set(int i);
13    public int get();
14  }
15  
16  class Luku implements LukuRajapinta {
17    int luku;
18    public Luku() {}
19    public Luku(int i) { luku = i; }
20    public int get() { return luku; }
21    public void set(int i) { luku = i; }
22    public String toString() { return ""+luku; }
23  }
24  
25  public class TaulukkoGenExt<TYPE extends LukuRajapinta> {
26  
27    public static class TaulukkoTaysiException extends Exception {
28      TaulukkoTaysiException(String viesti) { super(viesti); }
29    }
30  
31    private Class<TYPE> luokka; // = TYPE.class; Tyhmää, näin ei voi sanoa...
32    private TYPE alkiot[];
33    private int lkm;
34  
35    public TaulukkoGenExt(Class<TYPE> luokka) {
36      this(luokka,10);
37    }
38  
39    public TaulukkoGenExt(Class<TYPE> luokka,int koko) {
40      alkiot = (TYPE[])new Object[koko];
41      this.luokka = luokka;
42    }
43  
44    public void lisaa(int i) throws TaulukkoTaysiException {
45      try {
46        TYPE uusi = luokka.newInstance();
47        uusi.set(i);
48        if (lkm >= alkiot.length)
49          throw new TaulukkoTaysiException("Tila loppu");
50        alkiot[lkm++] = uusi;
51      }
52      catch (IllegalAccessException ex) {
53        throw new TaulukkoTaysiException("Laiton viittaus");
54      }
55      catch (InstantiationException ex) {
56        throw new TaulukkoTaysiException("Laiton uuden luonti");
57      }
58    }
59  
60    public String toString() {
61      StringBuffer s = new StringBuffer("");
62      for (int i=0; i<lkm; i++)
63        s.append(" " + alkiot[i]);
64      return s.toString();
65    }
66  
67    public void set(int i, int luku) throws IndexOutOfBoundsException {
68      if ( ( i < 0 ) || ( lkm <= i ) ) throw new IndexOutOfBoundsException("i = " + i);
69      alkiot[i].set(luku);
70    }
71  
72    public int get(int i) throws IndexOutOfBoundsException {
73      if ( ( i < 0 ) || ( lkm <= i ) ) throw new IndexOutOfBoundsException("i = " + i);
74      return alkiot[i].get();
75    }
76  
77    public static void main(String[] args) {
78      TaulukkoGenExt<Luku> luvut = new TaulukkoGenExt<Luku>(Luku.class);
79      try {
80        luvut.lisaa(0); luvut.lisaa(2);
81        luvut.lisaa(99);  // Tekee oikeasti luvut.lisaa(new Integer(99));
82      } catch ( TaulukkoTaysiException e ) {
83        System.out.println("Virhe: " + e.getMessage());
84      }
85      System.out.println(luvut);
86      luvut.set(1,4);
87      System.out.println(luvut);
88      int luku = luvut.get(2);  // oik: luku = (Integer)(luvut.get(2)).intValue();
89      System.out.println("Paikassa 2 on " + luku);
90      try {
91        luvut.set(21, 4);
92      }
93      catch (IndexOutOfBoundsException e) {
94        System.out.println("Virhe: " + e.getMessage());
95      }
96    }
97  }
98