2011-02-06 11 views
13

Il mio codice non può convertire da E a E. Posso fare un cast per digitare E, ma sembra ridondante in questa fase. Il mio array è già dichiarato come E-type. Java Generics, Can not Convertire da E a E

import java.util.Iterator; 

public class DataTypeDemo<E> 
{ 
private E[] data = (E[]) new Object [10]; 

public MyIterator newIterator() 
{ 
    return new MyIterator(); 
} 

private class MyIterator<E> implements Iterator<E> 
{ 
    private int location; 

    public boolean hasNext() 
    { 
     return location < data.length; 
    } 

    public E next() 
    { 
     return (data[location++]); // error here 
    } 

    public void remove() 
    { 
     throw new UnsupportedOperationException(); 
    } 
} 
} 

compilatore, getta questo errore:

DataTypeDemo.java:23: tipi incompatibili trovato: E richiesto: E

+1

Inserisci un esempio completo che consente ad altri di riprodurre il tuo errore. Altrimenti è improbabile che tu riceva aiuto. A proposito, hai controllato che non hai due classi chiamate "E" (in pacchetti diversi)? – sleske

+0

Qualsiasi motivo per cui non si sta utilizzando un 'Elenco '? Array e generici non suonano molto bene insieme. –

+0

@sleske: 'E' è un parametro di tipo sulla classe. In questo caso non esiste una classe chiamata "E". –

risposta

19

tuo tipo interno presenta una propria variabile di tipo:

private class MyIterator<E /* this is the problem*/> implements Iterator<E> 

E quindi sovrascrive la classe esterna Tipo di variabile

Modifica della dichiarazione del tipo a questo:

private class MyIterator implements Iterator<E> 

Riferimento:

  • Generics FAQ (anche se questo problema non è menzionato alla lettera, è implicito da questa FAQ)
5

La radice del tuo problema è che un interno classe del tuo. Per il compilatore, non ci sono garanzie che le due E siano dello stesso tipo.

import java.util.Iterator; 
import java.util.ArrayList; 


    public class DataTypeDemo<E> 
    { 
     private ArrayList<E> data = new ArrayList<E>(10); 

     private class MyIterator implements Iterator<E> 
     { 
      private int location; 

      public boolean hasNext() 
      { 
       return location < data.size(); 
      } 

      public E next() 
      { 
       return data.get(location++); 
      } 

      public void remove() 
      { 
       throw new UnsupportedOperationException(); 
      } 
     } 
    } 

Anche se una volta che sono a conoscenza del problema, sentitevi liberi di implementare la propria soluzione;)
Felice hacking.

5

Questo perché hai assegnato alla classe interna MyIterator il proprio parametro di tipo E. Si noti che lo E è un parametro di tipo diverso rispetto allo E della classe di inclusione (sono stati denominati entrambi E, ma sono due diversi parametri di tipo).

Basta lasciare fuori il parametro tipo per la classe interna:

private class MyIterator implements Iterator<E> { 
4

penso che il problema è che il tipo di iteratore nidificato viene definito come una classe generica anche parametrizzata su un tipo di nome non correlato E. Per risolvere questo, cambiare

private class MyIterator<E> implements Iterator<E> 

Per

private class MyIterator implements Iterator<E> 

questa prima dichiarazione dice che l'iteratore per il tuo tipo può essere parametrizzato su qualsiasi tipo, non solo sul tipo del contenitore esterno. Introduce anche una nuova variabile di tipo chiamata E che è separata dalla E nella dichiarazione esterna. Questa seconda definizione dice che per ogni tipo di contenitore esiste un tipo iteratore che non è generico rispetto al tipo esterno. Questo è probabilmente ciò che intendevi.