Sintaxis de inicialización de matriz cuando no está en una declaración

141

Puedo escribir:

AClass[] array = {object1, object2}

También puedo escribir:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

pero no puedo escribir:

AClass[] array;
...
array = {object1, object2};

¿Por qué está bloqueado esto por Java?

Sé cómo solucionarlo, pero de vez en cuando sería más simple.

Por ejemplo:

public void selectedPointsToMove(cpVect coord) {

    if (tab == null) {
        if (arePointsClose(coord, point1, 10)) {
            cpVect[] tempTab = {point1};
            tab = tempTab;
        } else if (arePointsClose(point2, coord, 10)) {
            cpVect[] tempTab = {point2};
            tab = tempTab;
        } else {
            cpVect[] tempTab = {point1,point2};
            tab = tempTab;
        }
    }
}

Esta simple pregunta que me ha estado molestando desde que aprendí a jugar con matrices en Java.

Jason Rogers
fuente
Perdón por el formato de texto, pero por alguna razón en China los botones de diseño de texto no aparecen: S
Jason Rogers
para el código, solo asegúrese de que esté sangrado con 4 espacios o más.
Mat
El otro problema es que tenía caracteres TAB en el código que pegó. Esto estropea el formato.
Stephen C
Gracias Oki, eclipse usa pestañas en la sangría, así que cuando copio y pego, arruina todo. gracias por la edición
Jason Rogers
Eclipse puede y debe reconfigurarse para que no use caracteres TAB para la sangría. Por favor, no uses eso como una excusa.
Stephen C

Respuestas:

137

¿Por qué está bloqueado esto por Java?

Tendrías que preguntar a los diseñadores de Java. Puede haber alguna razón gramatical sutil para la restricción. Tenga en cuenta que algunas de las construcciones de creación / inicialización de matrices no estaban en Java 1.0, y (IIRC) se agregaron en Java 1.1.

Pero "por qué" es irrelevante ... la restricción está ahí, y tienes que vivir con ella.

Sé cómo solucionarlo, pero de vez en cuando sería más simple.

Puedes escribir esto:

AClass[] array;
...
array = new AClass[]{object1, object2};
Stephen C
fuente
9
sin la nueva declaración, no habría diferencia entre un bloque de instrucciones y un inicializador de matriz (como en JavaScript, que puede ser engañoso)
bestsss
10
Se podría ser confuso ... y difícil de analizar. Considere si {o1()}era una expresión válida y si {o1();}era un bloque de declaración válido. El analizador tiene que llegar a '}' o ';' antes de que pueda distinguir los dos casos. ¡El problema gramatical no es sutil en absoluto!
Stephen C
19

Trataré de responder la pregunta del por qué: la matriz de Java es muy simple y rudimentaria en comparación con clases como ArrayList, que son más dinámicas. Java quiere saber en el momento de la declaración cuánta memoria debe asignarse para la matriz. Un ArrayList es mucho más dinámico y su tamaño puede variar con el tiempo.

Si inicializa su matriz con la longitud de dos, y luego resulta que necesita una longitud de tres, debe desechar lo que tiene y crear una matriz completamente nueva. Por lo tanto, la palabra clave "nueva".

En sus primeros dos ejemplos, usted dice en el momento de la declaración cuánta memoria asignar. En su tercer ejemplo, el nombre de la matriz se convierte en un puntero a nada y, por lo tanto, cuando se inicializa, debe crear explícitamente una nueva matriz para asignar la cantidad correcta de memoria.

Yo diría que (y si alguien sabe mejor, corrígeme) el primer ejemplo

AClass[] array = {object1, object2}

en realidad significa

AClass[] array = new AClass[]{object1, object2};

pero lo que hicieron los diseñadores de Java fue crear una forma más rápida de escribirlo si crea la matriz en el momento de la declaración.

Las soluciones sugeridas son buenas. Si el tiempo o el uso de la memoria es crítico en tiempo de ejecución, use matrices. Si no es crítico y desea un código que sea más fácil de entender y trabajar, use ArrayList.

prograde
fuente
2
Este es un acceso directo como usted ha dicho, citando a Oracle: "Alternativamente, puede usar la sintaxis de acceso directo para crear e inicializar una matriz" . La razón tal vez es que una matriz debe tener algo de espacio en la memoria usando new en algún momento. Nuevo está implícito en el acceso directo, pero el acceso directo solo es válido en la declaración. En otros lugares, no hay acceso directo permitido, y nuevo es obligatorio.
minutos
3
Lo siento, pero su intento de responder la pregunta "por qué" no retiene el agua. El compilador podría determinar qué tan grande debía ser la matriz contando las expresiones entre el {y el }... tal como lo hace para los formularios de inicializador que están permitidos.
Stephen C
8

No puedo responder por qué parte.

Pero si quieres algo dinámico, ¿por qué no consideras Collection ArrayList?

ArrrayList puede ser de cualquier tipo de objeto.

Y si como una compulsión lo quieres como una matriz, puedes usar el método toArray () en él.

Por ejemplo:

            ArrayList<String> al = new ArrayList<String>();
            al.add("one");
            al.add("two");
            String[] strArray = (String[]) al.toArray(new String[0]);

Espero que esto te pueda ayudar.

Amanpreet
fuente
2
No es necesario convertir el tipo de retorno de la matriz a la cadena []. Por contrato, la matriz devuelta es del mismo tipo que la matriz especificada. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal
4

Para aquellos de ustedes, a quienes no les gusta esta monstruosa new AClass[] { ... }sintaxis, aquí hay algo de azúcar:

public AClass[] c(AClass... arr) { return arr; }

Utiliza esta pequeña función como quieras:

AClass[] array;
...
array = c(object1, object2);
usuario123
fuente