2013-04-18 16 views
8

Ich habe versucht zu verstehen, ob es möglich ist, eine Methode zu erstellen, die basierend auf der Rückgabeklasse einen generischen Typ ableitet und eine statische Methode dieses generischen Typs aufruft.Java - Generische statische Methoden

d. H. Ich erstelle unten 2 Klassen, von denen beide die Methoden getInstances und getAllInstances implementieren. Ich versuche dann, die Methoden aus einem generischen Wrapper zu erstellen. Es scheint, dass die Superklassenmethode immer unabhängig vom Rückgabetyp ausgeführt wird.

Zum Beispiel

public class ParentClass { 

    public ParentClass(){} 

    public static <T extends ParentClass> T getInstance(){ 
     return (T) new ParentClass(); 
    } 

    public static <T extends ParentClass> List<T> getAllInstances(){ 
     ArrayList<ParentClass> parents = new ArrayList<ParentClass>(); 

     for(int i=0;i<5;i++){ 
      parents.add(new ParentClass()); 
     } 

     return (List<T>) parents; 
    } 

} 

SubclassA

public class SubclassA extends ParentClass{ 

    public SubclassA(){} 

    @SuppressWarnings("unchecked") 
    public static SubclassA getInstance(){ 
     return new SubclassA(); 
    } 

    @SuppressWarnings("unchecked") 
    public static List<SubclassA> getAllInstances(){ 
     ArrayList<SubclassA> parents = new ArrayList<SubclassA>(); 

      for(int i=0;i<5;i++){ 
      parents.add(new SubclassA()); 
      } 

     return parents; 
     } 
} 

Wrapper - zeigt das Problem

public class Wrapper { 

    public Wrapper(){ 
     // ... some other stuff 
    } 

    public <T extends ParentClass> T getInstance(){ 
     return T.getInstance(); 
    } 

    public <T extends ParentClass> List<T> getAllInstances(){ 
     return T.getAllInstances(); 
    } 

    public static void main(String... args){ 
     Wrapper wrapper = new Wrapper(); 

     SubclassA subclassA = wrapper.getInstance(); 
     ParentClass parentClass = wrapper.getInstance(); 

     System.out.println(subclassA.getClass().getName()); 
     System.out.println(parentClass.getClass().getName()); 
    } 

} 

Wenn Wrapper läuft ich die folgende Fehlermeldung erhalten:

Ex ception im Thread "main" java.lang.ClassCastException: ParentClass kann nicht in SubclassA umgewandelt werden at Wrapper.main (Wrapper.java:20)

Kann ich das in Java machen?

+0

verstehe nicht, was Sie hier erwarten .... Sie rufen eine statische Methode für eine Klasse, es wird ausgeführt. Warum sollte er den Aufruf an eine Unterklasse delegieren? und wie kann man feststellen, welche? – Gab

+0

Nun, die Hoffnung war, dass es bestimmen würde, an welche Subklasse delegiert werden soll, indem vom Rückgabetyp abgeleitet wird. Jetzt verstehe ich, dass Sie statische Methoden nicht übersteuern können, die Sinn macht. – user2294382

Antwort

1

Ihr Ansatz ist falsch, es gibt keine Vorstellung von statischen Inheritance in Java als Vererbung ist immer im Kontext der Object-Ebene. Nur Membermethoden (nicht statisch) können von Unterklassen mit entsprechenden Zugriffsmodifizierern vererbt werden.

Update: Darüber hinaus scheint in Ihrem Szenario Factory-Muster besser geeignet als Anpassung Generics zum Abrufen/Konstruieren bestimmter Klassenobjekte.

2

statische Methoden werden nicht override.This static Methoden werden zu Class Ebene gehört

1

Nein, man kann es nicht so. Damit es funktioniert können Sie das Class-Objekt übergeben:

public class ParentClassUtils 

    public static <T extends ParentClass> T getInstance(Class<T> clazz) { 
     return clazz.newInstance(); 
    } 

    public static <T extends ParentClass> List<T> getAllInstances(Class<T> clazz) { 
     List<T> list = new ArrayList<T>(); 
     for (int i = 0; i < 5; i++) { 
      list.add(getInstance(clazz)); 
     } 
     return list; 
    } 
} 

Auch in Ihrem Beispiel haben Sie äquivalente statische Methoden in übergeordneten Klassen und Unterklassen. Die Methoden der Unterklasse überschreiben nicht die Methoden der Elternklasse, sie verstecken sie nur, und das ist fast sicher nicht das, was Sie wollen. Dieser Utility-Class-Ansatz löst das Problem.