Sintaxe de inicialização de matriz quando não estiver em uma declaração

141

Eu consigo escrever:

AClass[] array = {object1, object2}

Eu também posso escrever:

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

mas não sei escrever:

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

Por que isso é bloqueado pelo Java?

Eu sei como contornar isso, mas de tempos em tempos seria mais simples.

Por exemplo:

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 pergunta simples que me incomoda desde que aprendi a brincar com matrizes em Java.

Jason Rogers
fonte
Desculpe sobre o formato de texto, mas por alguma razão na China os botões de layout de texto não aparecem: S
Jason Rogers
para código, verifique se está recuado com 4 espaços ou mais.
Mat
o outro problema é que você tinha caracteres TAB no código que colou. Isso atrapalha a formatação.
Stephen C
Oki obrigado, eclipse usa abas no recuo, então quando eu copio e colo atrapalha as coisas. obrigado pela edição
Jason Rogers
O Eclipse pode e deve ser reconfigurado para não usar caracteres TAB para indentação. Por favor, não use isso como desculpa.
Stephen C

Respostas:

137

Por que isso é bloqueado pelo Java?

Você teria que perguntar aos designers de Java. Pode haver alguma razão gramatical sutil para a restrição. Observe que algumas das construções de criação / inicialização da matriz não estavam no Java 1.0 e (IIRC) foram adicionadas no Java 1.1.

Mas "por que" é imaterial ... a restrição existe, e você tem que viver com ela.

Eu sei como contornar isso, mas de tempos em tempos seria mais simples.

Você pode escrever isto:

AClass[] array;
...
array = new AClass[]{object1, object2};
Stephen C
fonte
9
w / o a nova declaração não haveria nenhuma diferença entre um bloco de instrução e variedade initializer (como em javascript, o que pode ser enganosa}
bestsss
10
Ele iria ser confuso ... e difícil de analisar. Considere se {o1()}era uma expressão válida e {o1();}era um bloco de instrução válido. O analisador precisa chegar ao '}' ou ';' antes que possa distinguir os dois casos. A questão gramatical não é nada sutil !!
Stephen C
19

Tentarei responder à pergunta do porquê: O array Java é muito simples e rudimentar, comparado a classes como ArrayList, que são mais dinâmicas. Java deseja saber no momento da declaração quanta memória deve ser alocada para a matriz. Um ArrayList é muito mais dinâmico e seu tamanho pode variar ao longo do tempo.

Se você inicializar sua matriz com o comprimento de dois e, posteriormente, precisar de um comprimento de três, terá que jogar fora o que possui e criar uma nova matriz. Portanto, a palavra-chave 'new'.

Nos seus dois primeiros exemplos, você diz no momento da declaração quanta memória alocar. No seu terceiro exemplo, o nome da matriz se torna um ponteiro para nada e, portanto, quando é inicializado, você precisa criar explicitamente uma nova matriz para alocar a quantidade certa de memória.

Eu diria que (e se alguém souber melhor, por favor me corrija) o primeiro exemplo

AClass[] array = {object1, object2}

na verdade significa

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

mas o que os designers de Java fizeram foi facilitar a escrita, se você criar a matriz no momento da declaração.

As soluções alternativas sugeridas são boas. Se o tempo ou o uso da memória forem críticos no tempo de execução, use matrizes. Se não for crítico, e você deseja um código mais fácil de entender e trabalhar, use ArrayList.

progredir
fonte
2
Este é um atalho, como você afirmou, citando Oracle: "Como alternativa, você pode usar a sintaxe do atalho para criar e inicializar uma matriz" . Talvez a razão pela qual um array deva ter algum espaço na memória usando new em algum momento. Novo está implícito no atalho, mas o atalho é válido apenas na declaração. Em outros lugares, não há atalho permitido e o novo é obrigatório.
mins
3
Sinto muito, mas sua tentativa de responder à pergunta "por que" não retém a água. O compilador seria capaz de determinar o tamanho da matriz, contando as expressões entre o {e o }... exatamente como faz para os formulários inicializadores permitidos.
Stephen C
8

Não sei responder a parte do porquê.

Mas se você quer algo dinâmico, por que não considera Collection ArrayList.

ArrrayList pode ser de qualquer tipo de objeto.

E se, como compulsão, você desejar como uma matriz, poderá usar o método toArray ().

Por exemplo:

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

Espero que isso possa ajudá-lo.

Amanpreet
fonte
2
Não há necessidade de converter o tipo de retorno da matriz para String []. Por contrato, a matriz retornada é do mesmo tipo que a matriz especificada. docs.oracle.com/javase/6/docs/api/java/util/…
Ankur Agarwal
4

Para aqueles de vocês que não gostam dessa new AClass[] { ... }sintaxe monstruosa , aqui está um pouco de açúcar:

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

Use esta pequena função como você gosta:

AClass[] array;
...
array = c(object1, object2);
user123
fonte