|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 | |
|
Member
Iscritto dal: May 2007
Città: Roma
Messaggi: 93
|
[Java] Array di Generics
Domandona:
Qual'è il modo più elegante per creare un Array sfruttando il Generics? ve lo chiedo perchè non viene accettato il codice scritto in questo modo: Quote:
Spero che in un "Java 7" diano la possibilità di fare Array generici...
__________________
Più ti avvicini alla luce, più la tua ombra diventa grande (Kingdom Hearts - Walt Disney e Squaresoft, ma la mano è della Squaresoft) Ultima modifica di Dark Phoenix : 02-12-2007 alle 15:38. Motivo: Titolo migliore |
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Sep 2007
Messaggi: 754
|
Mi sono appena sveglaito dal riposino pomeridiamo e non vorrei dire inesattezze ma se usi una collection? tipo List
__________________
http://www.tevigroup.it/ |
|
|
|
|
|
#3 |
|
Member
Iscritto dal: May 2007
Città: Roma
Messaggi: 93
|
Non posso/voglio perchè è un fatto intrinseco del mio programma.
Cioè non voglio assolutamente che esista un modo per far crescere il buffer
__________________
Più ti avvicini alla luce, più la tua ombra diventa grande (Kingdom Hearts - Walt Disney e Squaresoft, ma la mano è della Squaresoft) |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Al momento si possono creare array solo di tipi "reifiable". Un tipo è reifiable se è completamente rappresentato a run-time. Ma i generics sono implementati tramite "erasure" e questo porta al fatto che a runtime non ci sono informazioni sui tipi parametrici. In Java il subtyping degli array è covariante. Integer[] è un sottotipo di Number[] che a sua volta è un sottotipo di Object[]. Questo viene permesso perché nell'oggetto che rappresenta l'array viene reificato (memorizzato) il tipo dell'array e ciò permette di controllare a runtime che non venga assegnato un oggetto di tipo incompatibile con l'array. Integer[] arr = new Integer[10]; Object[] objs = arr; objs[0] = "ciao"; // <-------- ArrayStoreException!! Un controllo a runtime di questo tipo non è possibile con i generics. Infatti è stato deciso che ArrayList<Integer> NON è un sottotipo di ArrayList<Number> o ArrayList<Object>. Proprio perché a runtime l'oggetto è solo un ArrayList e basta, non ci sono informazioni sul tipo da nessuna parte. Quindi array come ArrayList<Integer>[] o E[] (dove E una type variable) non sono istanziabili.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: May 2007
Città: Roma
Messaggi: 93
|
Grazie mille della spiegazione
A questo punto.... il modo più elegante sarebbe incapsulare gli elementi in una nuova classe utilizzante generics e fare un array di questa classe... mi spiego meglio: faccio un array di "ArrayObject" dove è Array Object ad utilizzare i generics. Oppure mi conviene fare un po come fanno le librerie standard che l'array se lo fanno passare? (e.g. ArrayList.toArray)
__________________
Più ti avvicini alla luce, più la tua ombra diventa grande (Kingdom Hearts - Walt Disney e Squaresoft, ma la mano è della Squaresoft) |
|
|
|
|
|
#6 | ||
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Le classi come java.util.ArrayList tengono internamente un array di Object e quando necessario, fanno un cast alla type variable. Una cosa del tipo: Codice:
....
private Object[] elements;
public T get (int index)
{
return (T) elements[index];
}
Quote:
Object[] toArray() <T> T[] toArray(T[] a) Il primo metodo restituisce un array in cui è reificato il tipo Object, indipendetemente dalla istanziazione della collezione. Non può fare altrimenti, visto che a runtime la collezione internamente non ha alcuna informazione sul tipo (per via della solita erasure). Nel secondo metodo le cose possono andare diversamente e viene restituito un array in cui è reificato il tipo esatto della istanziazione della collezione. Viene usata la reflection per poter fare ciò. Se tu hai un ArrayList<String> sei costretto (dal compilatore) a passare al secondo toArray un String[]. Tramite reflection, il metodo può sapere il tipo dell'array e sempre tramite reflection può creare un nuovo array con quel tipo. Un esempio può chiarire meglio: un metodo generico per creare un nuovo array che contiene N ripetizioni dell'array passato come argomento. Codice:
import java.lang.reflect.*;
public class Prova
{
public static void main (String[] args)
{
String[] arr1 = { "a", "b" };
String[] arr2 = repeatArray (arr1, 3);
for (String s : arr2)
System.out.print (s + " ");
}
public static <T> T[] repeatArray (T[] a, int count)
{
T[] out = null;
if (a != null)
{
out = (T[]) Array.newInstance (a.getClass().getComponentType(), a.length * count);
for (int i = 0; i < count; i++)
System.arraycopy (a, 0, out, i * a.length, a.length);
}
return out;
}
}
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) Ultima modifica di andbin : 03-12-2007 alle 21:48. |
||
|
|
|
|
|
#7 |
|
Member
Iscritto dal: May 2007
Città: Roma
Messaggi: 93
|
Ho capito!
Grazie andbin! Permettimi di dire: "Ammazza quante ne sai!"
__________________
Più ti avvicini alla luce, più la tua ombra diventa grande (Kingdom Hearts - Walt Disney e Squaresoft, ma la mano è della Squaresoft) |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:57.




















