2014-12-19 7 views
5

Vorrei scrivere un metodo generico che accetta un array e qualcos'altro. Ognuno dei quali potrebbe essere di qualsiasi tipo, ma devono essere uguali. Ho provato questo, ma potrei ancora inserire qualcosa nel metodo.Come scrivere un metodo che accetta un array di tipo x e un'altra variabile dello stesso tipo dell'array

public static <T> boolean arrayContains(T[] array, T object){ 
    return Arrays.asList(array).contains(object); 
} 

posso chiamare questo metodo con arrayContains(new String[]{"stuff"}, new Pig()) ma voglio soltanto di accettare arrayContains(new String[]{"stuff"}, "more stuff")

+0

Che dire di 'arrayContains (T object, T [] array)'? – JimmyB

+1

Il problema è che nel tuo caso 'T' diventa' Oggetto'. Non vedere alcuna soluzione tranne il tipo esplicitamente specializzato. – talex

+0

In questo caso, 'arrayContains', non ha molta importanza. Resterà semplicemente falso, perché un 'String []' non può contenere un 'Pig'. Ma comunque, è un 'Oggetto' in quel caso, come indicato sopra. – Bubletan

risposta

0

Questo è quello che ho finito per fare.

public static boolean arrayContains(Object[] array, Object object) { 
     if (array.getClass().getComponentType() != object.getClass()) { 
      throw new IllegalArgumentException("Type of array and object are not equal! " + array.getClass().getComponentType().getName() + " != " + object.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$ 
     } 
     return Arrays.asList(array).contains(object); 
    } 
0

Che dire dopo?

public static <A, E extends A> boolean arrayContains(A[] array, E object){ 
    return Arrays.asList(array).contains(object); 
} 

In questo caso il tipo del secondo argomento deve estendere (o essere uguale al) il tipo di elementi dell'array.

+0

L'elettore si preoccupa di commentare? –

+0

Questo non farà il trucco in Java 8. –

+0

Voglio usare Java 8 –

3

Quello che stai cercando di fare è complicato perché qualsiasi array (eccetto un array di primitive) è un Object[], così come hai notato, il metodo accetterà sempre qualsiasi array e qualsiasi oggetto.

Un modo per aggirare questo potrebbe essere quello di passare un Class oggetto esplicito, come questo

public static <T> boolean arrayContains(T[] array, T object, Class<T> clazz) 

Poi si potrebbe scrivere

arrayContains(new String[]{"stuff"}, "more stuff", String.class) 

ma non

arrayContains(new String[]{"stuff"}, new Pig(), String.class) 
+0

Non voglio farlo perché aggiunge solo un altro argomento che richiede tempo. –

-2

È necessario fornire più tipi parametrizzati, quindi fare qualcosa se non corrispondono.

public static <T, S> boolean arrayContains(T[] array, S object){ 
    System.out.println("array.class: " + array.getClass().getComponentType().getName()); 
    System.out.println("object.class: " + object.getClass().getName()); 
    System.out.println("array.class == object.class: " + (array.getClass().getComponentType() == object.getClass())); 

    // TODO: do something if the types don't match 

    return Arrays.asList(array).contains(object); 
} 
+0

Ho finito per usarlo e testare i tipi dell'oggetto. –

2

Non è possibile.

Oppure, in altre, qualsiasi matrice e qualsiasi riferimento già soddisfare la vostra esigenza, "matrice di tipo x e un altro varable con lo stesso tipo matrice", perché qualsiasi array è un "array di digitare Object "e qualsiasi riferimento dello stesso tipo (Object).

Quello che si desidera serve no tipo sicurezza scopo. Considera, ipoteticamente, che ci fosse un linguaggio per fare ciò che vuoi. Può operare solo sui tipi in fase di compilazione delle espressioni degli argomenti. Ma qualcuno può sempre fare questo:

Object[] foo = anyArrayExpression; 
Object bar = anyReferenceExpression; 
arrayContains(foo, bar); 

o

arrayContains((Object[])anyArrayExpression, (Object)anyReferenceExpression); 

(e, tra l'altro, nessuno di questi stanno facendo nulla di sospetto o pericoloso Un upcast è sempre sicuro al 100% e il funzionamento legit in. Java.)

Quindi qualsiasi array e qualsiasi riferimento possono sempre essere passati alla tua funzione in ogni caso, e la tua funzione deve sempre gestire gli oggetti reali essendo qualsiasi tipo di array e qualsiasi oggetto di tipo comunque. Quindi la tua funzione non ottiene nulla.

Anche se limitate per essere sottotipi di un certo tipo X, e la vostra funzione richiede solo X[] e X, può ancora essere sempre il caso che il classe di runtime effettivo degli oggetti puntato da riferimenti passati in sono Y[] e Z, dove Y e Z sono sottotipi non collegati di X. Questo è solo un fatto di come funziona il sistema di tipi Java. Quindi la tua funzione avrà sempre a che fare con il tipo di componente runtime dell'array potenzialmente non correlato alla classe runtime dell'altro oggetto, indipendentemente da come lo fai. (L'unica eccezione sarebbe se X fosse finale, quindi non ha sottoclassi, ma la restrizione sarebbe priva di significato perché sarebbe banalmente sempre vera)

Problemi correlati