java - Error "tipo genérico ilegal para instanceof" al usar clases locales
generics local-class (4)
Al parecer, al hacer Z compilación genérica tiene éxito.
Esperaba que se necesitara
<T>
como parámetro de tipo, pero solo hay que hacerlo genérico, así que cualquier cosa servirá.
import java.util.Arrays;
public class X<T> {
void m() {
class Z<Anything> {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
La solución adecuada sería calificar a la clase local, pero no creo que puedas. O lo refactorizas a una clase estática privada o es probablemente lo mejor que puedes obtener.
Tengo el siguiente código de Java que utiliza una clase local .
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {}
}
}
No se compila con el siguiente mensaje de error:
X.java:8: error: illegal generic type for instanceof
if (o instanceof Z) {}
^
1 error
Entiendo que la clase
Z
local hereda la firma de tipo genérico de
X<T>
, siendo una clase interna.
El mismo tipo de error de compilación aparece en este ejemplo, donde
Z
no es local, sino interno:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compilation error
}
}
Se puede trabajar alrededor haciendo que
Z
no sea interno / estático:
import java.util.Arrays;
public class X<T> {
static class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compiles now
}
}
O
calificando
XZ
:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3)) {
if (o instanceof X.Z) {} // Compiles now
if (o instanceof X<?>.Z) {} // Also
}
}
}
Pero, ¿cómo puedo calificar una clase local o evitar esta limitación, sin cambiar la clase local?
Esto debería funcionar bien. Usando la reflexión también. Pero parece una solución válida.
import java.util.Arrays;
public class X<T> {
void m() {
class Z2 {
}
for(Object o: Arrays.asList(1,2,3)) {
if(Z2.class.isAssignableFrom(o.getClass())) {
}
}
}
}
Para mí, esto parece ser un descuido o una limitación en el lenguaje Java y no creo que sea posible.
El tipo referenciado en una
instanceof
expresión debe ser verificable de acuerdo con
JLS 4.7
, lo que significa que debe expresarse como un tipo reificable por su nombre completo.
Al mismo tiempo,
JLS 6.7
establece que las clases locales no tienen un nombre completamente calificado, por lo tanto, no pueden expresarse como confiables.
Si declara Z como genérico, el operador
instanceof
trata a
Z
como un tipo en bruto en el que todas las propiedades genéricas, en este caso la clase que lo contiene, también se consideran en bruto.
(Similar a un método genérico de un tipo sin procesar que se considera como sin procesar a pesar de cualquier firma genérica. Esta es una medida para retener la compatibilidad con versiones anteriores de la generación de tipo). Dado que cualquier tipo sin formato es reificable, declarar que Z es genérico se compilará.
Una posible solución es usar la reflexión:
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}