2012-05-09 17 views
40

Duplicar posible:
Arrays constants can only be used in initializers error¿Por qué las constantes de matriz solo se pueden utilizar en los inicializadores?

estaba estudiando las matrices, y vine a través de este método de acceso directo de declarar e inicializar una matriz en una línea. Por ejemplo,

int[] a = {1, 2, 3, 4, 5}; 

Pero cuando traté de hacer siguiente código, Tengo este error del compilador diciendo "Las constantes matriciales sólo se pueden utilizar en inicializador".

int[] a; 
a = {1, 2, 3, 4}; 

¿Por qué?

+13

Esto no es un duplicado. El OP pregunta * por qué * no * cómo *. – Jeremy

+6

Meh; no está convencido de que sea una pregunta indirecta que diga "¿cómo lo hago para que funcione?", esta pregunta pregunta "¿por qué no funciona de otra manera?". La diferencia lleva a respuestas completamente diferentes: esta pregunta ya tiene * cómo * hacer que funcione. –

+0

Este tipo de preguntas son interesantes, pero casi imposibles de responder; todo lo que podemos hacer es especular. Sin embargo, sería realmente interesante preguntarle a quien escribió esa parte de la especificación, como un momento de enseñanza (¿por qué hiciste este diseño y no eso?). – yshavit

Respuesta

0

I java solo puede inicializar una matriz utilizando el primer método. No puedes asignar una matriz. Comprender por qué podría implicar alguna teoría sobre cómo se implementan las matrices. El compilador tiene que saber qué tan grande es una matriz cuando la matriz se declara, por lo que con la declaración y la inicialización en la primera línea, el compilador puede inferir el tamaño pero no el segundo.

+1

OP ya sabe que el segundo no funciona y pregunta * por qué *. La respuesta no aborda eso en absoluto. –

+0

por qué complier puede leer no de elemento en brasly rizado y conocer el tamaño de la forma en que lo hace en primer caso - int [] a = {1,2,3}; –

+0

java está tipado estáticamente por lo que el compilador debe saber el tamaño de la matriz en el momento de la inicialización para poder asignar memoria para la matriz. – cobie

84

No está permitido porque el JLS says so. La sintaxis solo está permitida en declaraciones y en expresiones de creación de matriz.

Estos últimos proporcionan una forma alternativa de conseguir el mismo resultado:

int[] a; 
a = new int[]{1, 2, 3, 4}; 

En cuanto a la razón subyacente real para exigir la new T[], mi conjetura es la siguiente. Considere la siguiente matriz de inicialización:

{1, 2, 3, 4} 

Se puede utilizar para inicializar matrices de diferentes tipos:

new int[]{1, 2, 3, 4}; 
new float[]{1, 2, 3, 4}; 
new double[]{1, 2, 3, 4}; 

Si no se requiere el bit new T[], sospecho que el desnudo {1, 2, 3, 4} podría causar dificultades durante análisis semántico Aquí, estoy pensando en casos como:

void f(float[] x) { ... } 
void f(double[] x) { ... } 
void g() { 
    f({1, 2, 3, 4}); 
} 

si se permitiera que esta sintaxis, la especificación de lenguaje tendría que hacer frente a la complejidad de la elección de qué función a llamar.

En una línea similar, no está claro cuál debería ser el tipo de {null}. Puede ser Object[], Integer[], Serializable[] y así sucesivamente.

Y, por último, la matriz vacía {} sería la más complicada de todas. Aquí, ni siquiera podemos decir si se trata de una matriz de objetos o una matriz de escalares.

En lugar de ocuparse de todas estas complejidades, parece que los diseñadores del lenguaje eligen evitarlas requiriendo la sintaxis new T[].

+0

que conozco pero mi pregunta es por qué no está permitido de esa manera? –

+0

Meh: el compilador conoce el tipo de 'arrn'. Podría comprar que es una simplificación del compilador, pero no hay nada tan difícil al respecto. –

+2

@DaveNewton: No necesariamente. Considere la posibilidad de que el '{1, 2, 3, 4}' desnudo pase a una función que está sobrecargada para 'float []' y 'double []'. ¿Qué debería pasar? – NPE

5

La respuesta corta es because the language spec says so.

¿Por qué? Sospecho que se trata de escribiendo.En el primer caso, el analizador sintáctico/compilador sabe que está dentro del contexto de inicialización de una variable de matriz, por lo que las llaves se pueden inferir como un inicializador de matriz.

En este último caso, no está inmediatamente claro de la línea lo que significan las llaves. Presumiblemente, el typer se ejecuta en una fase posterior de análisis sintáctico, de modo que no era factible simplemente inferir el significado.

Este argumento parece tener peso en el que se puede utilizar una sintaxis muy similar si específicamente (y técnicamente de forma redundante) declarar el tipo nuevo:

int[] a; 
// then later 
a = new int[] { 1, 2, 3, 4 }; 
+1

Java es famoso por su sintaxis "técnicamente redundante"; no hay "técnicamente" al respecto. –

0

La única respuesta que puede obtener es de naturaleza filosófica. La decisión de no permitir el tipo de matriz implícita está en línea con el principio de diseño general de Java para mantener las cosas simples y obvias. En el mismo sentido, podría preguntarse por qué cada downcast debe ser explícito, o cada conversión de tipo narrowing. Java es un lenguaje de cuello azul y obvio + explícito es su valor central.

Cuestiones relacionadas