# Generische Typen instanzieren



## Biesterfeld (21. Nov 2007)

Hi Leute,

hab ein doofes Problem. Gegeben sei folgender Beispielcode:


```
import java.util.ArrayList;
import java.util.List;

public class GenericsTest <T extends A>{
   
   private final List<T> list;
   
   public GenericsTest() {
      this.list = new ArrayList<T>();
      T toAdd = null;
      // toAdd = new T( 0 );
      // toAdd = T.getInstance( 0 );
      // toAdd = T.class.newInstance();
      this.list.add( toAdd );
   }
}
```

und


```
public class A {

   private final int x;
   
   public A( int x ) {
      this.x = x;
   }
   
   public static A getInstance( int x ) {
      return new A( x );
   }
}

public class B extends A {
   
   public B( int x ) {
      super( x );
   }

   public static A getInstance( int x ) {
      return new B( x );
   }
}
```

Soweit. Die auskommentierten Fehler im Konstruktor der Klasse GenericsTest sind augenscheinlich, veranschaulichen aber mein Problem. Ich würde gerne eine Instanz von einem Datentyp erzeugen, den ich zur Kompilierzeit gar nicht kenne. Ich würde gerne auf statische Eigenschaften von T zugreifen, was auch nicht geht.

Lässt sich sowas in Java gar nicht realisieren oder gibt es ein Muster, welches ein solches Problem löst?

Vielen Dank schonmal und viele Grüße
Biesterfeld


----------



## *Hendrik (21. Nov 2007)

Kannst Du das Objekt nicht im Konstruktor übergeben?


```
import java.util.ArrayList; 
import java.util.List; 

public class GenericsTest <T extends A>{ 
    
   private final List<T> list; 
   private T toAdd;
    
   public GenericsTest(T toAdd) { 
      this.list = new ArrayList<T>(); 
      this.toAdd = toAdd;
      this.list.add( toAdd ); 
   } 
}
```


----------



## Biesterfeld (22. Nov 2007)

Hi,



> Kannst Du das Objekt nicht im Konstruktor übergeben?


Kann ich nicht. Es geht konkret um einen Datei-Parser, der mir Abschnitte einer Text-Datei als Objekte zusammenbaut und in die Liste schiebt. Obwohl diese Abschnitte immer einem festgelegtem Format entsprechen, kann man sie je nach Datei noch weiter untergliedern. Daher verschiedene Klassen mit denen der Parser generisch zurechtkommen sollte.

Grüße
Biesterfeld


----------



## *Hendrik (22. Nov 2007)

Vielleicht mit dem Factory Muster?


----------



## Biesterfeld (22. Nov 2007)

Der Rückgabetyp einer Factory-Methode ist immer ein übergeordneter Datentyp. Das wollte ich gerne Vermeiden und eben daher mit Generics arbeiten. Wie es sich dreht und wendet ... ich habe zunehmend das Gefühl, das sich das was ich gerne hätte mit Generics nicht realisieren lässt. Nämlich dass das Objekt, dass von einem generischen Datentyp abhängt mir auch Objekte von genau dem Typ erzeugt.

Dennoch vielen Dank
Biesterfeld


----------



## SlaterB (22. Nov 2007)

wie willst du denn diese Liste anlegen?

wenn du irgendwo
GenericsTest<X> = new GenericsTest<X>();
hast, dann könntest du doch auch  
GenericsTest<X> = new GenericsTest<X>(new X());
schreiben?


----------



## Biesterfeld (22. Nov 2007)

> GenericsTest<X> = new GenericsTest<X>(new X());



Das bringt mir nur nichts, weil ich wie ich ja schon schrieb, einen FileParser habe, der nach und nach Objekte von X erzeugt. Was bringt es mir dann, genau ein Objekt X an den Parser zu übergeben?


----------



## SlaterB (22. Nov 2007)

dann könntest du noch beschreiben, wie die Situation wirklich ist,
und es findet sich doch eine Lösung,
dein obiger Code scheint nun wirklich nur ein Beispiel zu sein 


von dem einem Objekt könntest du dir übrigens die Klasse holen und dann newInstance() aufrufen, um mehr Objekte zu erzeugen 

oder du erstellst in GenericsTest eine abstrakte Operation:


```
public class Test
{

    public static void main(String[] args)
        throws Exception
    {
        GenericsTest<String> g = new GenericsTest<String>()
            {
                public String newT()
                {
                    return "Test";
                }
            };
    }
}


abstract class GenericsTest<T>
{

    private final List<T> list;

    public GenericsTest()
    {
        this.list = new ArrayList<T>();
        this.list.add(newT());
        System.out.println("list: " + list);
    }

    public abstract T newT();
}
```


----------



## Marco13 (22. Nov 2007)

Biesterfeld hat gesagt.:
			
		

> Der Rückgabetyp einer Factory-Methode ist immer ein übergeordneter Datentyp.



In der Hoffnung, das jetzt richtig verstanden zu haben: Nein. Seit Java 1.5 kann man kovariante Rückgabetypen verwenden.


```
interface Factory { Superclass create(); }

class A extends Superclass {}
class B extends Superclass {}

class FactoryA implements Factory { A create() { return new A(); }
class FactoryB implements Factory { B create() { return new B(); }
```


----------



## *Hendrik (22. Nov 2007)

Im Sinne von SlaterB?


```
class GenericTest<T extends A> {

    private final List<T> list;
    private Class<T> tClass;
    private T toAdd;

    public GenericTest() {
        this.list = new ArrayList<T>();
        try {
            toAdd = tClass.newInstance();            
        } catch (InstantiationException ex) {

        } catch (IllegalAccessException ex) {

        }
        this.list.add(toAdd);
    }
    
}
```


----------



## SlaterB (22. Nov 2007)

was meinst du mit 'in meinem Sinne'?
die NullPointerException bei tClass.newInstance(); ist nicht in meinem Sinne, nein


----------



## *Hendrik (22. Nov 2007)

:? NullPointerException ist auch nicht in meinem Sinne - ziehe meine letzten Beitrag hiermit zurück.


----------

