2012-07-24 14 views
5

EDIT: He cambiado un poco el ejemplo para conseguir la idea:¿Hay alguna manera de imitar o en genéricos de Java

Como

<Integer or Float> 

... sin tener que crear una interfaz común y hacer una subclase de Entero y el flotador para implementarlo

Si no, algo como esto sería tal vez tienen más sentido y ser útil

<E extends Number> <E = (Integer|Float)> 

¿Si? es un comodín ¿por qué no deberíamos permitirnos restringir ciertos tipos?

+1

¿Por qué quieres hacer eso? – Pshemo

+0

Parecen tiza y queso. El requisito no tiene ningún sentido para mí en absoluto. ¿Las entidades matemáticas Strings como Numbers se cierran sobre ciertas operaciones? No pensé. – duffymo

+0

Precisamente porque String es final, una o más soluciones se necesitarían aún más, porque no podríamos resolverlo con la alternativa que propongo – Whimusical

Respuesta

10

No es posible y apenas veo valor en él. Usas genéricos para restringir el tipo, p. Ej. en colecciones. Con el operador or sabes tanto sobre el tipo que conoces del supertipo más específico de ambos, Object en este caso. Entonces, ¿por qué no usar Object?

Hipotético:

List<E extends String or Number> list = //... 

¿Cuál es el tipo de list.get(0)? ¿Es StringoNumber? Pero no puedes tener una variable de ese tipo. No puede ser String, no puede ser Number - solo puede ser ... Object.

ACTUALIZACIÓN: Ya que ha cambiado su ejemplo en cuestión:

<Integer or Float> 

¿Por qué no simplemente decir:

<Number> 

? Tenga en cuenta que Number tiene métodos que le permiten extraer fácilmente floatValue() y intValue(). ¿Realmente necesitas el tipo exacto?


Tenga en cuenta que puede utilizarand operador:

<E extends Serializable & Closeable> 

Y eso tiene mucho sentido - se puede utilizar variable de tipo E donde sea se necesita Serializable o Closeable. En otras palabras, E debe extender tanto Serializable como Closeable. Ver también: Java Generics Wildcarding With Multiple Classes.

+0

Ok para la lista es estúpido, pero para otros usos podría no ser así. Incluso eso podría tener un String a = list.get (0) o bien un Integer a = list.get (0), feo pero no imposible o impracticle. Podría arrojar una CastExeption si el error – Whimusical

+2

@ user1352530: evitar 'ClassCastException' y compilar la comprobación del tipo de tiempo fue una de las razones para incluir los genéricos en primer lugar. –

+0

He actualizado la pregunta con una nueva aproximación que hace lo mismo para mí – Whimusical

1

No veo un uso real para eso ... Pero de todos modos, creo que lo más cercano que se puede llegar a ello es ampliar las interfaces comunes para las posibles implementaciones.

5

En casos muy extremos (anteriores a Java 7 sin AutoCloseable), me hubiera gustado poder hacer eso también. P.ej.

<E extends Connection or Statement or ResultSet> 

Eso hubiera permitido que llame a E.close(), sin importar el tipo real era. En otras palabras, E contendría la "intersección API" de todos los tipos suministrados.En este caso, contendría close() y todos los métodos de java.sql.Wrapper y java.lang.Object.

Pero desafortunadamente, no puedes hacer eso. En su lugar, use la sobrecarga de método, p.

void close(Connection c); 
void close(Statement s); 
void close(ResultSet r); 

O el viejo y simple instanceof

if (obj instanceof Connection) { 
    ((Connection) obj).close(); 
} 
else if (obj instanceof Statement) { //... 

o fijar su diseño, ya que probablemente no debería tener que intersectan las API de tipos arbitrarios de todos modos

+1

En Java 7 todas estas clases implementan ['AutoCloseable'] (http://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html) por lo que' 'es ahora suficiente. –

+0

''? – GriffeyDog

+0

@TomaszNurkiewicz: Lo sé. Es solo una ilustración. @GriffeyDog: Vea la respuesta de Tomasz. Los tipos de JDBC extienden 'AutoCloseable', no' Closeable' (que también se extiende 'AutoCloseable') –

Cuestiones relacionadas