Domanda

devo usare Java 1.4 e sto usando strutture ArrayList. Ora ho bisogno di fare un po 'ri-factoring e sarebbe d'aiuto se posso usare Generics. Attualmente ho codice come questo

ArrayList rows = new ArrayList();

Che è un ArrayList semplice. Ma ora la variabile "righe" sta diventando sempre più complesso e necessità di definire una classe di "Riga". Ora voglio fare qualcosa di simile a ciò che si vede in J2SE 1.5

ArrayList<Row> rows = new ArrayList();

Una rete da traino attraverso Google non espone alcuna risposta senza qualche uso sofisticato delle soluzioni 3rd party. Come sarebbe il mio codice dovuto cambiare per ospitare questo in 1.4, senza l'utilizzo di soluzioni di terze parti / progetti open source, (se possibile)?

È stato utile?

Soluzione

I generici sono stati introdotti nel JDK 1.5. Quindi non si possono utilizzare in 1.4. Tuttavia, si può essere in grado di utilizzare JDK 1.5 del compilatore, ma indirizzare 1.4 con le vostre classi opzione -target 1.4 javac con mentre l'opzione tenuta -source 1.5 per indicare che la sorgente è 1.5 compatibili. In questo caso è possibile utilizzare farmaci generici come esse non devono riguardare le classi di risultato.

veda la sezione sulle opzioni di Cross-compilazione

Altri suggerimenti

Generics tende ad affrontare il problema di ciò che io ritengo "calchi ingenuo" in Java 1.4 o precedente quando si tratta di collezioni. In Java 1.5 +, la linea si sono collocati:

ArrayList<Row> rows = new ArrayList();

darebbe un avvertimento, il codice generico corretta è

ArrayList<Row> rows = new ArrayList<Row>();

Questo dice al compilatore che l'oggetto ArrayList deve sempre e solo contenere il tipo di riga.

Tuttavia, dal momento che Java 1.5 è retrocompatibile con enormi set di librerie che non contengono che la sintassi, ma piuttosto il codice precedente:

ArrayList rows = new ArrayList();

Generics, ovviamente, non avrebbe funzionato con queste librerie più vecchie - quindi i generici sono solo momento della compilazione - le classi 1.5 e 1.4 sono effettivamente equivalenti (meno qualsiasi refactoring interno / nuovi metodi aggiunto in seguito), perché sono implementazioni veramente ArrayList che gestiscono ogni tipo di oggetto.

Il codice 1.5 aggiunge semplicemente un cast diretta per voi.

In 1.4 codice, dire che si voleva per scorrere l'ArrayList. Il modo getto ingenuo per farlo è il seguente:

for(Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) {
    Row row = (Row) rowIterator.next();
    // Do something with the row.
}

codice Java 1.5 di è esattamente equivalente alla versione getto ingenuo. Prende il fatto che si sta dicendo al compilatore che è di fila e fa che il codice per voi. Quindi, i benefici zucchero sintattico sono più belli (questo utilizza il più recente per ogni sintassi ciclo, ma genera lo stesso codice come il ciclo sopra):

for(Row row : rows) {
   // Do something with the row
}

Quindi, se si vuole utilizzare un ArrayList contenente solo le righe, è ancora possibile. Ma non c'è modo per ottenere il compilatore di di controllo che l'ArrayList contiene solo tutte le righe (anche se, anche se il compilatore fornisce questo controllo, è ancora possibile per inviare in un ArrayList che contiene altri tipi di oggetti, dal momento che, ancora una volta, l'ArrayList ancora gestisce veramente solo il tipo di oggetto, ed i farmaci generici vengono cancellati in fase di esecuzione -. non resta che il codice getto ingenua che non si vede più)

La variante non ingenuo è quello di controllare ogni istanza e gettare un ClassCastException te stesso con un messaggio informativo (piuttosto che avere l'unico programma tiro con il suo messaggio di default):

for(Iterator rowIterator = rows.iterator(); rowIterator.hasNext(); ) {
    Object shouldBeRow = rowIterator.next();
    if(!(shouldBeRow instanceof Row)) {
        throw new ClassCastException("The object " + shouldBeRow + " is not an instance of Row - only Rows should be present in the list!");
    }
    Row row = (Row) shouldBeRow;
    // Do something with the row.
}

Tuttavia, in generale non si fa questo -. Buona documentazione può fare questo problema discutibile, in quanto pone l'onere di fornire la raccolta corretta sul chiamante e quindi si può solo avere la ClassCastException gettato dalla JVM

Sì, è possibile. Utilizzare un compilatore 1,5, e l'uso

javac -target jsr14 ............

Questo genererà Java 1.4 classi, ma consentono farmaci generici.

Questo parametro può essere utilizzato solo per il codice non visibili byte 1,5 caratteristiche. Per esempio non è possibile utilizzare enumerazioni, o nuovi metodi introdotti nella 1.5. Ma generici vanno bene, in quanto non sono realmente presenti nel bytecode.

No, non è possibile utilizzarli in JDK 1.4. Essi sono stati introdotti in jdk1.5

Tutto quello che dovete fare loro è gettato. Questo potrebbe meritare un'eccezione di runtime se si mette tipi "sbagliato" nella lista.

Row arow = (Row) rows.get(0);

for ($i=0; i<rows.size(); $i++){
    Row element = (Row) rows.get($i);
    element.printCells();
    (...)
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top