• Wo Java doch Generics kann, sollte man diese doch auch nutzen. Aber irgendwie scheint die Umsetzung ein bisschen Pfusch zu sein...

    Also ich will in der Superklasse eine generische Funktion haben, damit ich das nicht in jeder Subklasse selbst implementieren muss. Diese Funktion konvertiert mir eine Liste in ein Generic Array (da sind dann aber natürlich noch ein paar andere Funktionen drin). Jedenfalls war das die Idee:

    Und jetzt würde ich mir davon einfach ein paar Klassen bauen, die das verwenden, also z.B. "public class AddressManager extends Manager<Address>"

    Allerdings kompiliert mir die Manager Klasse nicht, weil "Cannot create generic array of E" sowie "The cast from Object to E is actually checking against the erased type Object". Aha. Warum?!?

    Außerdem würd ich auch gerne meine PersistenceManager Abfragen generalisieren, also

    Code
    public E[] getList() {
            Query query = em.createQuery( "SELECT c FROM " + E.class.getName() + " AS c" );
            List resultList = query.getResultList();
            return convertListToArray( resultList );
        }

    Allerdings will er ein E.class.getName() auch nicht "Illegal class literal for the type of parameter E".

    Irgendwelche Vorschläge wie ich Java trotzdem dazu bringen kann meinen Code zu fressen (bzw. mir viel Copy&Paste zu ersparen)?

  • Das liegt an dem Type Erasure Process, der bei Java Generics zum Tragen kommt:

    Zitat


    When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

    Bruce Eckel hat das Thema Java Generics und type erasure mal sehr gruendlich dokumentiert:
    [ 1, 2, 3, 4 ]

  • Nachdems schon nen Generics Thread gibt, post ich gleich hier rein :) Folgender Code kompiliert bei mir unter Eclipse aber nicht mit javac:


    Und zwar schlaegt das Kompilieren in der Zeile L v = createObject(list.getClass()); fehl. Javac Output dazu:

    Code
    [javac] incompatible types
    [javac] found   : java.util.AbstractCollection
    [javac] required: L
    [javac]         L v = createObject(list.getClass());
    [javac]                           ^


    Kann mir einer erklaeren wieso, bzw. obs hier ne Loesung auch fuer den javac gibt?

    thx kubu


  • Du gibst bei der Methode createObject(); ein T zurück.
    Ein T und L sind beide von AbstractCollection abgeleitet, allerdings ist ein L kein T und umgekehrt.
    Deswegen kommt auch die Fehlermeldung incompatible Types. Du kannst einem L kein T zuweisen, weil die beiden nichts voneinander wissen.
    Warum das allerdings mit Eclipse kompiliert, kann ich beim besten Willen nicht verstehen.
    Hoffe das hat dir geholfen.
    Mfg.
    java-girl

    There's no better place than 127.0.0.1!

  • list.getClass() returned mir ja ein Objekt mit dem statischen Typ Class<? extends L>. Wenn ich damit die generische Methode createObject() aufrufe wird deren statischer Typ T gleich dem ? extends L und returned mir deshalb ein passendes Objekt vom statischen Typ ? extends L. Ich seh daran nicht, warum es nicht funktioneren sollte (und es funktioniert ja auch, unter Eclipse laeuft es einwandfrei).

    Bzw. hat das ueberhaupt mit dem Return-Typ zu tun? Der Fehler liegt ja anscheinend nicht am Return-Typ, sondern an dem Type des Parameters.


  • Also für mich ist das klar.
    Es geht nicht darum was du gerade beschrieben hast, es geht, wie gesagt darum, dass zwar der dynamische Typ in diesem Fall ein L ist, aber dass kann man zu diesem Zeitpunkt nicht wissen!
    Wenn du schreiben würdest

    Code
    AbstractCollection v = createObject(list.getClass());


    Dann würde es gehen...

    Verständlich?
    Die ganze Sache ist etwas verwirrend finde ich *g*

    There's no better place than 127.0.0.1!

  • Ne check ich immer noch nicht, sry wenn ich laestig bin :)
    L ist doch kein dynamischer Typ, sondern ein statischer. Wenn ich hab:

    Code
    AbstractList<Integer> v = new Vector<Integer>();
    filter(func, v);


    Dann hat L doch den Typ AbstractList<Integer>. Wenn ich den an createObject weitergebe wird Class<T> cl von createObject() zu Class<AbstractList<Integer>> und T dadurch AbstractList<Integer>.


  • So, jetzt muss ich mich einmal entschuldigen.
    Ich war vollkommen auf dem falschen Dampfer und ehrlich gesagt weiß ich nicht was es da haben kann. Sorry für die Verwirrung die ich gestiftet hab!!!
    Eigentlich müsste es wirklich gehen....

    There's no better place than 127.0.0.1!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!