Visualizzazione dei risultati da 1 a 3 su 3

Discussione: generic method

  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2008
    Messaggi
    813

    generic method

    ciao a tutti,
    ho creato una classe Utilities per la mia applicazione dove vado a mettere vari metodi statici per fare delle operazioni varie, che non riesco ad accorpare ad altre classi. Ho creato questo metodo

    codice:
    public static <T> T[] arrayRange(T[] A, Interval interval)
        {
            T[] range = (T[])new Object[interval.length()];
    
            for(int i=0;i<range.length;i++)
            {
                range[i] = A[(i+interval.getFrom())%interval.getMax()];
            }
            
            return range;
        }
    il funzionamento è semplice: prende un range di un array più lungo. Lo so che c'è il metodo copyRange sulla classe Arrays, ma questo funziona solo se from<to (io posso avere casi in cui from>to, poiché gli array sono circolari).
    il metodo funziona bene, ma c'è un solo problema quando la richiamo. Ecco un caso

    PolarPoint [] subsetBorderA = Utilities.arrayRange(bordersA,mA);
    ovviamente bordersA è di tipo PolarPoint[].
    Ecco il problema: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lmelecon.algorithm.xmath.PolarPoint;

    Perché a compilation-time nessuna lamentela, ma a run-time questa?!?! Neanche mettendo un cast esplicito a PolarPoint[] riesco ad arginare il problema.
    soluzioni? Vi ringrazio anticipatamente
    Nell'anno 1968 è bastata la potenza di due Commodore 64 per lanciare con successo una navicella sulla Luna; nell'anno 2007 ci vogliono la potenza di un processore quad core 3.30 GHz e 3 Gb di RAM (requisiti minimi ufficiali) per utilizzare Windows Vista. Qualcosa deve essere andato storto!

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

    Re: generic method

    Originariamente inviato da Hysoka
    PolarPoint [] subsetBorderA = Utilities.arrayRange(bordersA,mA);
    ovviamente bordersA è di tipo PolarPoint[].
    Ecco il problema: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lmelecon.algorithm.xmath.PolarPoint;

    Perché a compilation-time nessuna lamentela, ma a run-time questa?!?! Neanche mettendo un cast esplicito a PolarPoint[] riesco ad arginare il problema.
    No, perché il problema è proprio in cosa è stato "reificato" (termine strano che indica cosa è rappresentato a runtime) nell'array.

    L'array l'hai istanziato di Object, è "reificato" il tipo Object.

    Nella tua riga

    PolarPoint [] subsetBorderA = Utilities.arrayRange(bordersA,mA);

    Il compilatore sotto-sotto per il valore di ritorno ci infila un cast a PolarPoint[] (perché arrayRange ritorna T[]).

    PolarPoint [] subsetBorderA = (PolarPoint[]) Utilities.arrayRange(bordersA,mA);

    Ma se l'array è realmente un Object[] .... non può essere un PolarPoint[] e non può essere convertito a questo!!!

    Hai presente le collezioni come es. LinkedList che hanno (vedi javadoc) questi due metodi?

    Object[] toArray()
    <T> T[] toArray(T[] a)

    Il primo fa proprio quello che hai fatto tu (istanzia un Object[]) ma lo rende chiaro mettendo come tipo di ritorno Object[]. Un metodo così serve solo quando non ti importa davvero tanto di che tipo è l'array (se è Object[]) ma ti importa solo degli oggetti contenuti.

    Se ti interessa il tipo dell'array, con le collezioni devi usare il secondo metodo. Ma questo metodo non istanzia un Object[]! L'unico modo per istanziare un array del giusto tipo è quello di ricevere un array (infatti ha il parametro) e usare la "reflection" di Java per istanziare dinamicamente l'array "copiando" il tipo.

    Ti suggerisco di guardare il sorgente di LinkedList per quel secondo toArray. Oltre a trovare la soluzione lo troverai "istruttivo" ...
    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
    Registrato dal
    Feb 2008
    Messaggi
    813

    Re: Re: generic method

    Originariamente inviato da andbin
    Ti suggerisco di guardare il sorgente di LinkedList per quel secondo toArray. Oltre a trovare la soluzione lo troverai "istruttivo" ...
    ho guardato il sorgente di copyRange e usa la classe Array di reflective.
    grazie cmq
    Nell'anno 1968 è bastata la potenza di due Commodore 64 per lanciare con successo una navicella sulla Luna; nell'anno 2007 ci vogliono la potenza di un processore quad core 3.30 GHz e 3 Gb di RAM (requisiti minimi ufficiali) per utilizzare Windows Vista. Qualcosa deve essere andato storto!

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.