2009-07-30 23 views
7

Se ho una classe StackJava Tipo Raw e generici interazione

class Stack<E> {} 

Ora, se faccio:

1) Stack<Integer> s = new Stack()

2) Stack s = new Stack<Integer>()

3) Stack s = new Stack()

qualcuno può spiegarmi che cosa queste interazioni (generano ic < -> raw) causa?

Principalmente il mio dubbio è sul punto 1. In effetti, se lo faccio, non è sicuro perché lo stack può memorizzare tipi diversi da Integer. Sì, ma se ho un metodo push e provo a memorizzare un valore diverso da un intero il compilatore mi ferma ... quindi quando avrò quell'operazione non sicura?

+0

Non capisco - vuoi avere uno stack in cui puoi spingere altre cose poi gli interi (es. Interi e doppi) o vuoi usare lo stack solo con un tipo (intero) e lasciare che il compilatore Aiutarti? –

+1

No Voglio uno stack con un tipo e voglio sapere cosa succede se eseguo i compiti . – xdevel2000

risposta

6

Tutti questi non sono sicuri perché i generici di Java, in virtù di type erasure, sono solo zucchero sintattico. Ad esempio, questo codice Java è interamente valido:

Stack<Integer> s = new Stack<Integer>(); 
Stack<Double> s2 = (Stack<Double>)s; 
s2.push(3.3d); 

Il punto dei generici Java è che non è necessario essere espliciti sulla trasmissione di oggetti. Questo è tutto. Non fanno nulla di più (tranne generare avvisi di compilatore e IDE).

Sono ancora utili e possono rendere il codice molto più leggibile e meno soggetto a errori, ma alla fine, a livello di codice byte, è importante capire che non stanno facendo nulla.

+0

non è il caso n. 2 dell'OP in cui il compilatore è abbastanza intelligente da dedurre gli argomenti di tipo generico per s? –

+0

Sì, ma nel punto 1 il compilatore mi consiglia se provo a inserire (con un'operazione push) un oggetto diverso da un numero intero. Quindi i generici non sono solo uno "zucchero sintattico", ma il punto 1 cambia anche il comportamento del compilatore (la semantica). Quindi di nuovo non capisco dov'è il non sicuro ... Dovrei, per favore, darmi una spiegazione più analitica? – xdevel2000

7

Tutti e tre sono perfettamente legali, poiché non esiste una differenza di runtime effettiva tra uno Stack e uno Stack<Integer>, ma tutti e tre comporteranno gli avvisi del compilatore.

Stack<Integer> s = new Stack() 

Questo si tradurrà in un avvertimento "conversione incontrollato", perché non è sicura, in generale, per convertire un tipo grezzo a un tipo parametrico. Tuttavia, è perfettamente sicuro farlo in questo caso: la spinta dei valori Integer non causerà alcun errore; spingendo valori non Integer causerà un errore di tipo.

Stack s = new Stack<Integer>() 

Questa è una conversione legale di un tipo parametrico a un tipo grezzo. Sarai in grado di spingere il valore di qualsiasi tipo. Tuttavia, qualsiasi operazione di questo tipo genererà un avviso di "chiamata non verificata".

Stack s = new Stack() 

Ancora, questo è legale, senza conversione implicita. Sarai in grado di spingere il valore di qualsiasi tipo. Tuttavia, qualsiasi operazione di questo tipo genererà un avviso di "chiamata non verificata".

È inoltre possibile ricevere un avviso di "tipo non elaborato" ogni volta che si fa riferimento al tipo Stack.