2013-05-20 25 views
5

Sto cercando di capire i metodi generici in Java. Dato il codice seguente:Informazioni sui metodi generici java

public class GenericTest { 

    interface Shape { 
     public long area(); 
    } 

    public static class Triangle implements Shape 
    { 
     private long base, height; 
     public long area() { return (base * height)/2; } 
    } 

    public static class Rectangle implements Shape 
    { 
     private long width, height; 
     public long area() { return width * height; } 
    } 

    public <T extends Shape> long area1(T shape) 
    { 
     return shape.area(); 
    } 

    public long area2(Shape shape) 
    { 
     return shape.area(); 
    } 

} 

non riesco a vedere/capire perché devo usare/attuare area1 anziché area2 (o viceversa). Mi sto perdendo qualcosa? Non entrambi i metodi fanno la stessa cosa?

E mi ha lasciato un po 'confuso per quanto riguarda i farmaci generici in Java

+1

In questo caso non ha senso usare i generici. I casi in cui * ha * un senso sono, quando non sai che tipo di tipi devi ** memorizzare **. –

+1

In questo caso, come @LukasKnuth ha affermato che non è necessario creare una versione generica dell'area area() è accettabile; Tuttavia la documentazione oracle corrente mostra grandi esempi di generici. Gli esempi generici di caratteri jolly possono anche aiutare a chiarire la confusione ... .ha un'occhiata a http://docs.oracle.com/javase/tutorial/extra/generics/methods.html –

+0

Stavo guardando i generici come un equivalente approssimativo di C++ modelli. La cosa fondamentale che hai indicato qui è che manca dalle altre risposte (e probabilmente quello che mi manca è il concetto che sono usate "quando non sai di che tipo ** memorizzare **". Quale è esattamente quello che stavo cercando nella risposta :-) – Xaq

risposta

4

Non v'è alcuna buona ragione per la creazione del metodo area1. Il metodo area2 è preferibile. I generici devono essere usati quando esiste una relazione con un tipo specifico ma sconosciuto. Qui, non c'è nulla di specifico sul parametro shape. L'interfaccia Shape ci consente già di utilizzare il metodo area, quindi non ci interessa quale implementazione specifica di Shape venga passata come shape. Quindi i generici non sono necessari qui.

Usa

public long area2(Shape shape) 
13

Nel tuo esempio, dal momento che il parametro T tipo non viene utilizzato in tutti i valori di ritorno, non v'è alcuna differenza.

Tuttavia, Immagina di avere i seguenti metodi:

public <T extends Shape> T movedShape1(T shape) { 
    return shape.move(); 
} 

public Shape movedShape2(Shape shape) { 
    return shape.move(); 
} 

Qui potete vedere un chiaro vantaggio di utilizzare movedShape1(). Ottieni un tipo più specifico per il tuo valore di ritorno, senza perdere alcun tipo di sicurezza.

+0

Non è ancora lo stesso? Non vedo la sicurezza del tipo extra, entrambi restituiscono Shape non è vero? – Xaq

+2

@Xaq: Se si ha una classe 'Circle implementa Shape', quindi chiamare' movedShape1() 'con un parametro' Circle' restituirà un 'Circle', non un' Shape'. Chiamare 'movedShape2()' con lo stesso parametro 'Circle' darebbe un' Shape'. – Keppil

+0

@Xaq, Keppil ha ragione, ed è super utile quando chiami un metodo del genere. – dantuch

0

In questo caso, la forma non è una classe (astratta) ma un'interfaccia, quindi deve essere implementata (estesa nella forma di pensiero di gnerics) - Direi che sono esattamente uguali, e aggiungendo i generici c'è solo shadowing cosa sta realmente accadendo