Visualizzazione dei risultati da 1 a 3 su 3

Discussione: Array di oggetti

  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2006
    Messaggi
    99

    Array di oggetti

    Ciao a tutti, ho 1 problema, non riesco a creare un array di oggetti da me creati, insomma ho creato una classe mia di nome PositionSequence<E> e devo creare un array di oggetti di questo tipo, purtroppo però ho un eccezzione di questo tipo: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LSequenza.PositionSequence; Ecco il semplice esempio:

    import Sequenza.PositionSequence;

    public class prova<E>{

    PositionSequence<E> array[];

    public prova(){
    array = (PositionSequence<E>[])new Object[100];
    }

    public static void main(String[] args){
    prova<Integer> p = new prova<Integer>();
    }
    }

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Array di oggetti

    Originariamente inviato da doping
    Ciao a tutti, ho 1 problema, non riesco a creare un array di oggetti da me creati, insomma ho creato una classe mia di nome PositionSequence<E> e devo creare un array di oggetti di questo tipo, purtroppo però ho un eccezzione di questo tipo: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LSequenza.PositionSequence;
    Qui c'è da entrare nei "meandri" più complicati dei "generics". Partiamo dall'inizio.
    Per via della ben nota "erasure", il tipo PositionSequence<E> non è un tipo "reifiable" (reificabile), motivo per cui non è possibile creare un array di questo tipo. Per dirla con del codice:

    PositionSequence<E>[] arr = new PositionSequence<E>[100]; // ERRORE

    non è possibile, è un "generic array creation" e viene segnalato come errore dal compilatore.

    La tua riga che rimodello qui per semplicità:

    PositionSequence<E>[] arr = (PositionSequence<E>[]) new Object[100];

    dal punto di vista della compilazione è accettata, salvo un "unchecked warning" sempre per via della erasure (il cast non è controllabile né in compilazione né a runtime perché in nessuno dei due casi si può sapere cosa sarà quel 'E').
    Ma il fatto è che se un array viene creato proprio di tipo Object[] non può essere di certo un PositionSequence[] quindi il cast fallisce a runtime.

    La soluzione più semplice e pratica è quella di usare una collezione (es. ArrayList) invece di un array.

    Esempio:

    codice:
    class ArrPosSeq<E>
    {
        ArrayList<PositionSequence<E>> arrList;
    
        public ArrPosSeq ()
        {
            arrList = new ArrayList<PositionSequence<E>> ();
        }
    
        public void add (PositionSequence<E> ps)
        {
            arrList.add (ps);
        }
    }
    Poi per usarlo, ad esempio:

    codice:
    ArrPosSeq<Integer> aps = new ArrPosSeq<Integer> ();
    
    PositionSequence<Integer> psint = new PositionSequence<Integer> ();
    
    aps.add (psint);
    Questo evita i problemi citati all'inizio ed elimina gli unchecked warning.


    Un'altra soluzione è quella di creare l'array proprio come Object[] e di fare un cast (unchecked) a PositionSequence<E> dove serve.

    Esempio:

    codice:
    class ArrPosSeq<E>
    {
        Object[] arr;
        int pos;
    
        public ArrPosSeq ()
        {
            arr = new Object[100];
        }
    
        public void add (PositionSequence<E> ps)
        {
            arr[pos++] = ps;
        }
    
        public PositionSequence<E> get (int index)
        {
            return (PositionSequence<E>) arr[index];   // unchecked cast ma ok a runtime
        }
    }
    Un array di Object può contenere reference a qualunque cosa .... quindi anche a tipi PositionSequence<E>.


    Un'ulteriore soluzione è una leggera variante di quella appena detta. Invece di usare come tipo dell'array Object si usa PositionSequence ovvero si usa il "raw type" di PositionSequence<E>.

    codice:
    class ArrPosSeq<E>
    {
        PositionSequence[] arr;
        int pos;
    
        public ArrPosSeq ()
        {
            arr = new PositionSequence[100];
        }
    
        public void add (PositionSequence<E> ps)
        {
            arr[pos++] = ps;
        }
    
        public PositionSequence<E> get (int index)
        {
            return (PositionSequence<E>) arr[index];     // unchecked cast ma ok a runtime
        }
    }
    Internamente cambia poco e visto dall'esterno nulla.


    Come hai potuto vedere, sei appena andato a "cozzare" contro una delle parti più complesse ed oscure dei generics. Quindi prima di partire in quinta con quello che stavi facendo, valuta bene cosa fare e se è la scelta giusta.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Aggiungo ancora una cosa, che purtroppo non mi è venuta subito in mente prima. Esiste ancora un'ulteriore possibilità che probabilmente è quella che si avvicina di più a quello che forse volevi fare tu.
    Usare come reference per l'array un PositionSequence<E>[] e istanziare l'array usando però il "raw type", al costo come al solito di un unchecked warning.

    codice:
    PositionSequence<E>[] arr;
    
    ...
    
    arr = (PositionSequence<E>[]) new PositionSequence[100];   // unchecked cast ma ok a runtime.
    Il warning di unchecked cast si è solo spostato rispetto al mio ultimo esempio, invece di essere nel o nei punti dove serviva un PositionSequence<E>, è nel punto della assegnazione dell'array.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.