inpopup=true&id=89103
Em Java, o operador new é usado para alocar memória dinamicamente. Este operador, como todos sabem, é usado para instanciar
objetos e para criar arrays.
Memória do Computador
A memória de um computador pode ser entendida como sendo um gigantesco array. Cada posição deste array é chamado de endereço
de memória.
Um programa, para que possa ser executado, precisa estar armazenado em algum local na memória. As variáveis, por fazerem parte do
programa, também estão em aluma posição (endereço) na memória.
Variáveis em Java
Toda variável ocupa (gasta) alguns bytes da memória. A quantidade de bytes depende do tipo da variável. Por exemplo, se uma variável é
do tipo int entãoela ocupa, em algum local, 4 bytes (32 bits).
Variáveis Primitivas
Variávei primitivas são usadas para representar números, caracter e valor lógico (booleano). Assim, por exemplo, no fragmento de código
int i;
1 de 7 21/9/2010 20:40
http://moodle.ufsc.br/mod/resource/view.php?inpopup=true&id=89103
i = 40;
Variáveis primitivas são chamadas de variáveis estáticas. A palavra estática, neste contexto, significa que a quantidade de bytes
alocados para que a variável possa armazenar um dado é definida durante a compilação do programa. Assim, no exemplo acima, o simples
fato da variável "i" estar declarada implica que ela já está ocupando 4 bytes, mesmo que ainda não tenhamos atribuído nenhum valor à
variável.
Variáveis Referência
Variáveis referência são usadas para representar objetos e arrays. Contudo, estas variáveis não armazenam objetos e arrays "dentro
delas". Se isso fosse possível, a quantidade de bytes gastos por uma variável dependeria da quantidade de atributos da classe do objeto
ou então do tipo e tamanho do array.
As variáveis referência armazenam o endereço (posição no array memória) onde estão localizados os objetos ou arrays. Por causa disso,
estas variáveis são chamadas de variáveis dinâmicas ou ponteiros (pointers em inglês).
int[] v;
v = new int[6];
dizemos que:
2 de 7 21/9/2010 20:40
http://moodle.ufsc.br/mod/resource/view.php?inpopup=true&id=89103
como a variável "v" é dinâmica, ela armazena endereço de memória (e não outro tipo de dado).
a expressão "new int[6]" deve ser compreendida da seguinte forma:
ao ser executada, a Máquina Virtual Java (MVJ) procurará na memória um local com 24 (6 * 4) bytes livres. Encontrando este
local, os 24 bytes são reservados para que seja possível armazenar, no futuro, 6 números inteiros. Em cada posição deste
array o valor inicial é o número zero.
se a MVJ não conseguir encontrar 24 bytes livres na memória então a execução do programa é interrompida porque
literalmente não há memória suficiente.
se a MVJ conseguiu encontrar 24 bytes livres na memória então estes 24 bytes estão localizados em algum local, algum
endereço. Considera-se que o endereço do array é a posição do primeiro dos 24 bytes. Este endereço é o valor resultante da
avaliação da expressão "new int[6]" e será o valor atribuído à variável "v".
dizemos então que a variável "v" não contém o array (se fosse assim "v" teria que ocupar 24 bytes da memória) mas sim o
endereço onde está localizado o array. Dito de outra forma, a variável "v" aponta para o array.
ao final da execução do comando de atriuição, terão sido gastos 28 bytes de memória: 24 bytes necessários para armazenar 6
números inteiros e mais 4 bytes da variável "v" para armazenar o endereço deste array.
Se uma variável "x" é dinâmica, do tipo referência na terminologia Java, então o comando de atribuição só pode ser usado para atribuir
valores do tipo endereço de memória a esta variável. As únicas formas de se atribuir um valor para este tipo de variável são:
x = new ...; // o valor de x será o endereço onde foi alocado um objeto ou um array
Observe que, nos três casos acima, o comando de atribuição funciona como sempre funcionou: ele é usado para atribuir um valor a uma
variável.
Nos casos acima, é possível saber o endereço onde está localizado o objeto ou o array pois o endereço é o valor da variável x.
3 de 7 21/9/2010 20:40
http://moodle.ufsc.br/mod/resource/view.php?inpopup=true&id=89103
Passagem de parâmetros
Na linguagem Java a passagem de parâmetros se dá por valor. Assim, por exemplo, na expressão
o.m(p);
o objeto "o" está recebendo a ordem "execute o método "m" sendo que este método exige um valor que será o valor da expressão "p".
o.m(m2()); // o valor da expressão é o valor resultante da execução do método m2 que deve retornar um dado do tipo int
int v = 10;
m(v);
System.out.println(v);
...
4 de 7 21/9/2010 20:40
http://moodle.ufsc.br/mod/resource/view.php?inpopup=true&id=89103
Porque em Java só existe passagem de parâmetros por valor sabemos que o valor que será mostrado na tela (System.out.println(v)) é 10
pois na invocação do método m a variável "v" só é usada para definir o valor do parâmetro. Em outras palavras, a variável "v" definida no
método "m" não tem nenhuma relação com a variável "v" declarada no início do fragmento Java. É apenas uma coincidência que estas
duas variáveis tenham recebido o mesmo nome.
v[0] = 34;
v[1] = 25;
v[2] = 68;
m(v);
System.out.println(v[0]);
...
Qual será o valor exibido na tela quando a expressão "Sytem.out.println(v[0]);" for executada? 34 ou 99?
Vamos imaginar que a expressão "new int[3]" tenha retornado o endereço 5B9 (número hexadecimal) ou no endereço 5B9 foi alocado um
array capaz de armazenar 3 números inteiros.
A execução da expressão "m(v)" pode ser traduzida da seguinte forma: execute o método "m" levando como parâmetro o valor da
variável "v", ou seja, o endereço 5B9 onde está localizado um array.
5 de 7 21/9/2010 20:40
http://moodle.ufsc.br/mod/resource/view.php?inpopup=true&id=89103
Quando o método m vai ser executado, a primeira coisa que é feita é definir o valor da variável "k". No exemplo em questão, o valor de
"k" será o endereço 5B9. Assim, a variável "k" "sabe" que no endereço 5B9 existe um array de números inteiros.
A expressão "k[0] = 99" pode ser traduzida da seguinte forma: altere o valor do primeiro número do array que está localizado no
endereço indicado pela variável "k".
Durante a execução do método "m" nós temos duas variáveis ("v" e "k") que apontam para o mesmo array. Portanto, como só existe um
único array, qualquer alteração feita nele é "permanente".
Em termos práticos dizemos que quando um array é passado como parâmetro qualquer alteração nele será permanente. Sabemos agora
porque isso acontece: não é o array que é passado como parâmetro mas sim o seu endereço.
O mesmo raciocínio se aplica quando a variável representa um objeto. Não passamos objetos como parâmetros, mas sim o endereço dos
objetos.
Ao passarmos como parâmetro um endereço temos o mesmo efeito da passagem de parâmetros por referência. Mas, lembre-se, em Java
só existe passagem de parâmetros por valor.
A título de curiosidade, se houvesse passagem de parâmetro por referência em Java, o valor mostrado na tela para fragmento de código
Java seria 5. No entando, será mostrado o valor 3 pois a variável "v" aponta para um array de tamanho 3.
m(v);
System.out.println(v.length);
...
6 de 7 21/9/2010 20:40
http://moodle.ufsc.br/mod/resource/view.php?inpopup=true&id=89103
7 de 7 21/9/2010 20:40