Resultado incorrecto devuelto por isAbstract () de la clase Modificadora


A mi entender el siguiente código debería imprimir False, sin embargo cuando ejecuté este código está imprimiendo True.

De Java docs:

Devuelve true si el argumento integer incluye el modificador abstracto, falso de lo contrario.

public class Test{
    public static void main(String[] args) {
        System.out.println(Modifier.isAbstract(byte[].class.getModifiers())); 
    }
}

¿Puede alguien ayudarme a entender este comportamiento ?

Author: Show Stopper, 2018-07-16

5 answers

El Javadoc de en java.lang.Clase.getModifiers() especifica lo que debe devolverse para algunos de los modificadores de los tipos de matriz (por ejemplo, el modificador final debe ser true y el modificador interface debe ser false). Por otro lado, no especifica cuáles deben ser los modificadores abstract o static para los tipos de matriz, lo que significa que la decisión de devolver true o false no está documentada en el JDK. Por lo tanto, cualquier implementación puede optar por devolver bien true o false.

Int java.lang.Clase.getModifiers()

Devuelve los modificadores del lenguaje Java para esta clase o interfaz, codificados en un entero. Los modificadores consisten en las constantes de la Máquina Virtual Java para public, protected, private, final, static, abstract y interface; deben ser decodificados usando los métodos de class Modifier.

Si la clase subyacente es una clase array, entonces su público, privado y protegido los modificadores son los mismos que los de su tipo de componente. Si esta Clase representa un tipo primitivo o void, su modificador público es siempre true, y sus modificadores protegidos y privados son siempre false. Si este objeto representa una clase de matriz, un tipo primitivo o void, entonces su modificador final siempre es true y su modificador de interfaz siempre es false. Los valores de sus otros modificadores no están determinados por esta especificación.

El las codificaciones de modificadores se definen en la Especificación de Máquina Virtual Java, tabla 4.1.

 50
Author: Eran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 06:56:02

Una pista de este comportamiento se puede encontrar en el JLS, 10.8. Objetos de clase para matrices :

Cada matriz tiene un objeto de clase asociado, compartido con todas las demás matrices con el mismo tipo de componente.

Aunque un tipo de matriz no es una clase, el objeto de clase de cada matriz actúa como si: [snipped]

Bajo este razonamiento, una matriz no es una clase "real", por lo que definitivamente no es una clase concreta. La misma lógica se aplicaría a int.class siendo considerado abstracto.

 6
Author: Mureinik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 06:43:28

La definición de resumen dice:

Una clase abstracta es una clase que está incompleta, o que debe considerarse incompleta.

Si hubiera un array puro como [] entonces estaría incompleto ya que no se proporciona ningún tipo de componente.

Esto violaría la especificación de 15.10.1. Expresiones de Creación de Matrices :

Es un error en tiempo de compilación si el ClassOrInterfaceType no denota a reifiable tipo.

No solo denota un tipo reifiable, sino ningún tipo en absoluto. Por lo tanto, sería imposible crear instancias de [], al igual que para las clases abstractas.

Dado que no hay una matriz pura [] esto es solo una especie de especulación. Además los modificadores fueron devueltos para byte[]. Sigue siendo la especificación mostrada por Eran.

 3
Author: LuCio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 06:39:48

Mi explicación sería que los arrays se consideran abstract porque son instanciados por la propia JVM.

Simplemente no existe ninguna clase concreta para ningún tipo de matriz.

Un array tiene un contrato definido por el JLS :

  1. Índice de accesibilidad
  2. Aplicación para Cloneable y Serializable

Pero nadie, excepto el propio Lenguaje, puede cumplirlas, porque realmente no podemos declarar una implementación nosotros mismos.

 2
Author: Lino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 06:45:20

Desde mi punto de vista, la especificación del lenguaje java para getModifier () es:

Si la clase subyacente es una clase de matriz, entonces su público, privado y los modificadores protegidos son los mismos que los de su tipo de componente. Si esta Clase representa un tipo primitivo o void, su modificador público siempre es cierto, y sus modificadores protegidos y privados son siempre false

Ahora, los valores de sus otros modificadores no están determinados por esta especificación por ejemplo, ABSTRACT.

Del cuadro 4.1-A de JVMS:

ACC_ABSTRACT 0x0400 Declared abstract; no debe ser instanciado.

 2
Author: Show Stopper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-16 06:49:25