2010-04-19 20 views
36

Mi piacerebbe scrivere un metodo che possa accettare un tipo param (o qualunque sia il metodo in grado di capire il tipo da) e restituire un valore di questo tipo in modo da non dover eseguire il ritorno genere.Tipo di ritorno generico Java

Ecco un metodo:

public Object doIt(Object param){ 
    if(param instanceof String){ 
     return "string"; 
    }else if(param instanceof Integer){ 
     return 1; 
    }else{ 
     return null; 
    } 
} 

Quando chiamo questo metodo, e passare una stringa, anche se so che il tipo di ritorno sarà una stringa devo cast dell'oggetto di ritorno. Questo è simile al parametro int.

Come devo scrivere questo metodo per accettare un tipo param e restituire questo tipo?

+2

Una domanda importante è se si utilizzerà sempre String e int. Se è così, non vuoi un metodo generico. Si vogliono due metodi, uno che accetta e restituisce un int e un altro che accetta e restituisce una stringa. –

risposta

67

se non si vuole avere una specifica interfaccia per gestire quella roba è possibile utilizzare un metodo generico in questo modo:

public <T> T mymethod(T type) 
{ 
    return type; 
} 

presente che in in questo modo il compilatore non sa nulla del tipo che si intende utilizzare all'interno di tale metodo, quindi è necessario utilizzare un tipo associato, ad esempio:

public <T extends YourType> T mymethod(T type) 
{ 
    // now you can use YourType methods 
    return type; 
} 

Ma dovresti essere sicuro di aver bisogno di un metodo generico, il che significa che l'implementazione di doIt sarà la stessa per tutti i tipi con cui prevedi di usarla. In caso contrario, se ogni applicazione è diversa solo sovraccaricare i metodi, che funzionerà bene dato tipo di ritorno non viene utilizzato per binding dinamico:

public String my(String s) 
{ 
    return s; 
} 

public int my(int s) 
{ 
    return s; 
} 

int i = my(23); 
String s = my("lol"); 
10

iniziare con questo:

public interface Command<T> 
{ 
    T execute(T parameter); 
} 
0

vorrei vi esorto a NON uso instanceof, tuttavia questo codice fa quello che vuoi:

public class Main 
{ 
    public static void main(String[] args) 
    { 
     final Main main; 
     final String strVal; 
     final Integer intVal; 
     final Float floatVal; 

     main  = new Main(); 
     strVal = main.doIt("Hello"); 
     intVal = main.doIt(5); 
     floatVal = main.doIt(5.0f); 

     System.out.println(strVal); 
     System.out.println(intVal); 
     System.out.println(floatVal); 
    } 

    public <T> T doIt(final T thing) 
    { 
     T t; 

     if(thing instanceof String) 
     { 
      t = (T)"String"; 
     } 
     else if (thing instanceof Integer) 
     { 
      t = (T)Integer.valueOf(1); 
     } 
     else 
     { 
      t = null; 
     } 

     return (t); 
    } 
} 
+0

dal tuo esempio potresti semplicemente usare l'overloading invece di usare un metodo generico, dal momento che il tipo di ritorno non è usato per il dynamic binding .. – Jack

+1

ovviamente, stavo solo cercando di dare la risposta che fosse il più vicino possibile al codice pubblicato. Penso che il codice postato nella mia risposta sia una pessima idea e non lo userei, nonostante faccia ciò che si desidera :-) – TofuBeer

8

La risposta breve è no. Non appena viene coinvolto il numero instanceof, Generics di solito è la risposta sbagliata. Utilizzare invece i metodi sovraccaricati:

public String doIt(String param){ 
    return "string"; 
} 

public Integer doIt(Integer param){ 
    return 1; 
} 

public Object doIt(Object param){ 
    return null; 
} 
+2

6 anni dopo ... detto questo, se il tipo dichiarato è 'Object', questo ha vinto funziona come l'overloading dei metodi viene eseguito in fase di compilazione in base al tipo dichiarato della variabile. – Powerlord

+0

, ad esempio, se si ha 'Object var =" Bacon ";' poi, nonostante sia un 'String', verrebbe chiamato' doIt (Object param) '. – Powerlord

Problemi correlati