[quote=java]Em C quando queriamos que uma função modificasse o valor da variável que era passada por parametro usavamos o operador & que passava o endereço da memória…
char b='c';
mudavalor(b&); // aqui o método mudavalor poderia alterar o conteúdo da variável b
Em VB temos que informar obrigatoriamente no parâmetro da função ou método que é por valor (val) ou por referência (ref)
Tem como fazer isso no JAVA?
[/quote]
Como Java é uma linguagem moderna teve tempo de aprender desses exemplos. Em Java temos 4 tipos de variáveis primitivas: numericos (int,long,short, etc…), logicos (boolean) , caracter (char) e de referencia.
As variáveis de referencia guardam um numero (tal como todas as outras) que representa o endereço na JVM do objeto. Esse numero depende da implementação da JVM e o programador não precisa saber qual é.
Bom, quando um primitivo é passado como argumento é sempre por valor. Como todos os tipos em Java são primitivos, então todos são passados por valor.
int a = 3;
inc(a);
inc(int b){
b++;
}
Isto significa que a e b tem o mesmo valor, mas não são a mesma variável. Alterar b , altera apenas b e nunca a. Embora existam práticas que afirmam que todos os argumentos devem ser declarados final, isso é completamente desnecessário já que a JVM garante que a variável é sempre passada por valor.
Quando se passa uma variável de referencia, o principio é o mesmo, já que vc nunca está passando o objeto , mas sim a variável que o referencia. Entenda que um numero qualquer de variáveis podem referenciar o mesmo objeto e por isso não faz sentido passar o objeto.
Mas como isto influencia o uso ?
Bom, em C e VB um objeto é um tipo especial de variável. Quando vc declara uma variável como um objeto a variável é realmente o objeto.
Em C vc pode pegar um objeto e obter a sua referencia (com o &) ou o seu ponteiro com (*) ou seja, vc parte do objeto e pega um tipo mais simples que é a referencia. Isto permite q vc trabalhe com 3 conceitos explicitamente. Em VB vc não trabalha com pode obter a referencia (já que ela não serve para nada) mas pode dizer se quer usar passagem por valor ou por referencia. Nestas linguagens passa por valor significa: copia o objeto para outro objeto e passa esse novo objecto - repare , ele copia o objeto todo. E passar por referencia significa: passa este objeto.
Então no que o Java é diferente ? É diferente no conceito de que o objeto não é um tipo de variável e portanto, não tem como copiar o objeto em si. Apenas a referencia a ele. Ora, o que sempre queremos é passar a referencia de forma a usar dentro do método o mesmo objeto que nos foi passado. Se quisermos copiar o objeto ele próprio usamos, explicitamente, o método clone().
Mas porque sempre o java passa por valor e nunca por referencia ?
Porque se passase por referencia o codigo a seguir seria um tremento problema:
SomeObject a = new SomeObject();
destroy(a)
a.setProperty(34565);
destroy(Object b){
b= null;
}
Se fosse por referencia, ou setar b para null (ou seja, limpado a referencia ) a invocação a.setProperty() daria um NullPointerException
Em Java ,realmente como tudo é passado por valor , isto nunca acontece. Ou limpar b, vc está limpando b e não a.
O motivo para isto é mais sutil. O motivo para passar sempre por valor é para criar uma delimitação coerente entre os escopos das variáveis. Coisa que C e VB não fazem e por isso são aquela zona. Delimitar o escopo das variáveis, por sua vez é extremamente importante para o GC saber quando o objeto não é mais referenciado. Quando se sai de um método, por exemplo, todas as variáveis usadas dentro dele são limpas automaticamente o que evita que vc faça um monte de x = null manualmente.
Moral da historia: Não ha sequer porque se preocupar com o tipo de passagem em Java porque só ha uma. A maravilha, é que uma só resolve tudo o que vc quiser fazer.