Que tipo de objeto é um array?

Estou achando o array muito estranho, quando imprimo o CanonicalName ele sempre mostra a classe que contém o array com “[]” na frente, tipo:

java.lang.String[]
br.com.meu.pacote.qualquer.MyClass[]

etc…

Acontece que essas classes não existem, vc não pode dar um import nelas, por exemplo. Aliás os caracteres [] não são permitidos na declaração da classe. Isso está parecendo um xunxo. Alguém poderia explicar melhor?

Arrays são classes especiais criadas pela máquina virtual (logo elas existem sim, mas só em tempo de execução, não de compilação).

int[] -> Array de int.
java.lang.String[] -> Array de String.
br.com.meu.pacote.qualquer.MyClass[] -> Array de MyClass.
int[][] -> Array de array de int.
java.lang.String[][] -> Array de array de String.

Você dá import no tipo base do array. Imports só servem para dizer ao compilador o que os nomes curtos de classe significam. Desta forma, ao encontrar "Date" e tiver nos imports "java.util.Date", ele vai saber que o Date é uma abreviação de java.util.Date. Há também a classe java.sql.Date, mas se ela não estiver nos imports, o compilador saberá que se trata de java.util.Date.
É a mesma coisa que você dizer que há um João da Silva e chamá-lo simplesmente de João. Mas pode haver algum João Oliveira em outro lugar.

O array por si só, o compilador já sabe perfeitamente o que é por causa dos colchetes. Logo ele só precisa de ajuda (imports) para saber o significado do tipo base.

http://java.sun.com/docs/books/jls/third_edition/html/arrays.html

Um array é um objeto de uma classe gerada a partir da sua classe componente. Por exemplo, se o tipo do componente é java.lang.String, o tipo de um String[] é java.lang.String[], e se o tipo do componente é java.lang.String[], o tipo de um String[] é java.lang.String[][].

Todas as classes arrays definem os seguintes membros:

public final int length ; 
public Object clone(); 

Os métodos de java.lang.Object não são redefinidos, apenas herdados. Em particular, public String toString() retorna sempre algo como “[L/java/lang/String@123ab” ou coisa parecida, não uma representação do array, e public boolean equals (Object obj) sempre compara apenas as referências, não o conteúdo do array.

Analisar a saída do método abaixo:

public static void main(String[] args) { String[] s = new String[5]; System.out.println(s.getClass().getCanonicalName()); System.out.println(s.getClass().getComponentType().getCanonicalName()); }

Saída:

java.lang.String[] java.lang.String

Outra coisa estranha em arrays é que se T instanceof U, então T[] instanceof U[].

Por exemplo:

Object[] obj = new String[10]; // válido

Esse tipo de coisa foi abandonado na linguagem Scala, porque provoca mais problemas que os resolve.

Outra coisa: como você viu, você pode fazer

Class<?> klass = (new String[10]).getClass();

Mas não pode instanciar um array só com seu objeto java.lang.Class. Em vez disso, é necessário fazer isto aqui:

Class<?> klass = String.class; // por exemplo
String[] str = (String[]) java.lang.reflect.Array.newInstance (klass, 10);

até onde eu sei Arrays são estruturas de dados, assim como LinkedList e outros!!

flws

[quote=aeciovc]até onde eu sei Arrays são estruturas de dados, assim como LinkedList e outros!!

flws[/quote]

Não são. São bem diferentes. A máquina virtual faz tratamento especial para arrays (e bem especial). Já LinkedList não tem nenhum tipo de tratamento especial na JVM.

[quote=victorwss][quote=aeciovc]até onde eu sei Arrays são estruturas de dados, assim como LinkedList e outros!!

flws[/quote]

Não são. São bem diferentes. A máquina virtual faz tratamento especial para arrays (e bem especial). Já LinkedList não tem nenhum tipo de tratamento especial na JVM.[/quote]

Só para ter uma idéia, a JVM, ao ver o seguinte código:

int[] x = new int[1000];
for (int i = 0; i < x.length; ++i) {
    x[i] = -1;
}

faz algumas otimizações violentas, do tipo "já que você quer percorrer o array inteiro, desde a posição 0 até a final, não preciso checar se vai estourar o array (“range check”) e “já que você quer preencher o array com um valor apenas, vou chamar uma instrução especializada do processador para fazer isso para você”.

Isso ele não faz, habitualmente, para um ArrayList.

Então o array é um caso a parte no universo java 8)

Sim, mas isso não é uma particularidade do Java.

Interessante que ninguém mencionou a tradução da palavra Array, que é Vetor.

Array é, nada mais nada menos, do que um vetor de n posições contendo dados do tipo especificado.

Ex:

O vetor names é um vetor que, nesse caso, contém duas posições, dois nomes (tipo String).

[code]int[] codes = new int[20];

codes[0] = 20;
codes[20] = 15;[/code]
O vetor codes é um vetor de 20 posições em que podem ser armazenados valores do tipo int.

Capiche?

:wink:

Bom dia!

Então, sabem uma forma de fazer um índice do array ser um final? Tipo (a sintaxe não funciona, é um exemplo)

int[] i = {final 1,2,3};

Ou seja que eu não consiga alterar uma posição (ou todas) de um array por ser final:

Tem como?

Obs.: é só curiosidade mesmo

[quote=fausto]Bom dia!

Então, sabem uma forma de fazer um índice do array ser um final? Tipo (a sintaxe não funciona, é um exemplo)

int[] i = {final 1,2,3};

Ou seja que eu não consiga alterar uma posição (ou todas) de um array por ser final:

Tem como?

Obs.: é só curiosidade mesmo
[/quote]

Nunca vi isso.

Uma coisa que você pode usar é isso:Abacaxi[] a = ... List<Abacaxi> b = Collections.unmodifiableList(Arrays.asList(a));Usar List em lugar de array é bem melhor.

Em Java tudo o que é final (static ou não, tanto faz para o que direi, não confundam) é constante, mas isso está sujeito a algumas regras…

Se for variável primitiva, o valor determinado é fixo e imutável. Ex:

Esse número é 10 pra sempre (enquanto a instância da classe durar, claro).

Se for um objeto (incluindo array, String, Wrappers como Integer e Double… tudo o que não é variável primitiva em Java é objeto), a instância associada à variável final não pode ser trocada, mas os valores internos da instância podem. Ex:

Vejam a classe:

public class Pessoa{ public String nome; public int idade; public Pessoa(String nome, int idade){ this.nome = nome; this.idade = idade; } }
Vejam as variáveis finais:

private final Pessoa p = new Pessoa("Carlos", 21); private final Integer num = Integer.valueOf(10);
Ambos são objetos. o tipo Integer é uma classe Wrapper, que “empacota” / “embrulha” um valor primitivo int e ainda oferece métodos auxiliares para processamento do dado. Se eu quiser posso modificar os valores contidos nesses objetos. Instanciadas essas constantes, isso é legal:

Vejam que não mudei a instância, só o valor de um atributo.

Isso é ilegal:

Já que tenta mudar a instância de Pessoa associada à constante p.

Resumindo: mesmo um array constante como esse:

Pode ter os seus valores alterados, já que esse array é um vetor de dados do tipo int, portanto é um objeto.