2 Stimmen

Casting einer Liste<> in java?

Hallo, ist es möglich, eine Liste zu erstellen?

Ich habe eine abstrakte Klasse, die eine Methode, die irgendeine Art von List<> nimmt, iterieren durch es in einer for-Schleife immer jedes Objekt in dieser Liste und Aufruf der insertItem abstrakte Methode, die von der Unterklasse implementiert wird, um im Grunde ziehen Sie die richtigen Daten in die Elemente und dann finaly Einfügen Sie in eine Datenbanktabelle hat.

Hier ist die Methode der Superklasse:

protected void insertAllItemsToDb(List<Object> items, String table) {
        // open db and table

        database().beginTransaction();
        // clear all data from table
        clearTable(table);
        // call a insert statement to insert each column from an item
        for (Object object : items) {
            insertItem(object, table);
        }
        // close db
        database().endTransaction();
        database().close();
    }

In der Unterklasse ist hier eine der Überschreibungsmethoden: Die ich bin in der Lage, das Objekt hier gut zu casten.

  @Override
    protected void insertItem(Object object, String table) {

        CalendarEventItem item = (CalendarEventItem) object;
        eventItemValue = new ContentValues();

        eventItemValue.put(LABEL_EVENTS_TITLE, item.getEventTitle());
        eventItemValue.put(LABEL_EVENTS_LOCATION, item.getEventLocation());
        eventItemValue.put(LABEL_EVENTS_DATE, item.getEventStartTime()
                .getDate());
        eventItemValue.put(LABEL_EVENTS_TIME, item.getEventStartTime()
                .getTime());
        eventItemValue.put(LABEL_EVENTS_TIMEZONE, item.getEventStartTime()
                .getTimeZone());

        database.insert(TABLE_NAME_EVENTS, null, eventItemValue);

    }

dann rufe ich diese Methode von der Superklasse aus mit dieser auf:

events =  (List<CalendarEventItem>) items;
        insertAllItemsToDb(events, TABLE_NAME_EVENTS);

Aber ich erhalte einen Kompilierfehler, der besagt, dass man es nicht werfen kann. Irgendwelche Ideen, wie ich dies erreichen kann, ohne die gleichen Schritte und Code zu duplizieren, die Sie innerhalb der insertAllItemsToDb() sehen

6voto

Sean Patrick Floyd Punkte 283617

Verwenden Sie einen Typ-Parameter

Fügen Sie der abstrakten Klasse einen generischen Parameter hinzu:

public abstract class BaseClass<T>{

    protected abstract void insertItem(T object, String table);

    protected void insertAllItemsToDb(List<T> items, String table) {
        //...
        for (T object : items) {
            insertItem(object, table);
        }
        //...
    }

}

Jetzt brauchen Sie kein Casting mehr, eine untergeordnete Klasse muss nur noch den richtigen Typ verwenden:

public class FooBar extends BaseClass<Phleem>{
    protected void insertItem(Phleem object, String table){
        // ...
    }

}

5voto

Andrzej Doyle Punkte 99892

A List<Object> es no a List<CalendarEventItem> also hat der Compiler recht, dass sie nicht gecastet werden können. Für einen schnellen Grund, warum, hier ist ein Beispiel:

final List<Object> listOne = new ArrayList<Object>();
listOne.add("Hello World");

final List<CalendarEventItem> listTwo = new ArrayList<CalendarEventItem>();
listTwo.addAll(listOne); // Correctly disallowed by compiler

// This is what you're trying to do
List<CalendarEventItem> sneakyList = (List<CalendarEventItem>)listOne;
listTwo.addAll(sneakyList);

Daher ist das Casting zwischen zwei inkompatiblen Typen nicht zulässig, da es die Garantien für die Typsicherheit zerstören würde.

Sie wollen mit Sicherheit Ihre insertAllItemsToDb Methode zur Aufnahme einer List<?> und nicht eine List<Object> da es Ihnen egal ist, was der Elementtyp ist, solange es eine Unterklasse von Object ist (was trivialerweise wahr ist).

Dies sollte verhindern, dass Sie zwischen nicht konvertierbaren Typen wechseln müssen, und ist im Allgemeinen viel angenehmer zu handhaben.

Weitere Informationen finden Sie im Abschnitt Wildcard-Grenzen in Angelika Langers hervorragendem FAQ zu Java-Generika . Sie sollten sich das Ganze ansehen, wenn Sie es nicht schon getan haben. Das allgemeine Prinzip, das Sie mitnehmen sollten, ist, dass in Die meisten Fälle sollten Sie wahrscheinlich Wildcards auf Sammlungen für Methodenargumente verwendet werden - die einzige Zeit, die Sie nicht ist, wenn Sie sowohl lesen aus und schreiben in die Sammlung (die eigentlich überraschend selten ist).

0voto

Bal Punkte 2008

Sie könnten auch einfach den Methodenparameter als reguläre Liste deklarieren und ihn dann in eine beliebige generische Liste innerhalb der Methode umwandeln, d.h. Ihre Methode wäre protected void insertAllItemsToDb(List items, String table) und die erste Zeile, die Sie werfen würden: List<CalendarEventItem> newItems = (List<CalendarEventItem>) items ... natürlich die Implementierung jeglicher Art von Überprüfung/Fehlerabfangung, die Sie bei einer solchen Aktion durchführen sollten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X