saoj:
Muita gente acha que Java passa argumentos por referencia.
Na verdade ele passa uma cópia da referencia, ou seja, é impossível mudar uma referencia externa passada para dentro de um método via argumento.
Em C dá para fazer isso mole como o famoso &var:
Sim. E o operador de referência, no C++ e no C, é ainda mais restrivo que o do Java. Isso porque no C++ uma referência não pode mudar de valor (embora a variável que ela aponta possa).
Por exemplo, é impossível fazer isso aqui:
void UmaClasse::umMetodo(UmaOutraClasse& objeto) {
objeto = new UmaOutraClasse(); //Erro, tentou alterar o valor da referência
}
No Java isso é permitido.
Porém, só vamos alterar o valor da referência interna, não o valor da referência externamente.
saoj:
String s = new String("asdfasdf");
// ref de s = 111222
muda(&s);
// ref de s = 333222
Em Java isso é impossível, porque a referencia é sempre copiada, logo não tem como alterar a que ficou do lado de fora. Isso é maravilhoso para segurança. Em Java, a segurança de um objeto imutável, é quase que total.
Ops... acho que você confundiu alguma coisa aí. No C++ é praticamente impossível alterar um objeto imutável, mesmo desse jeito. E no Java, é possível alterar um objeto que foi recebido como referência:
public void add10NaLista(List<Integer> lista) {
lista.add(10);
}
//Em outro momento
List<Integer> umaLista = new Lista();
this.add10NaLista(umaLista); //10 é realmente adicionado na lista
Por que ele faz uma cópia é da referência, não do conteúdo para onde a referência aponta. O que não é possível é isso aqui:
public void zerarX(Xis x) {
x = new Xis();
}
Xis x1 = new Xis();
x1.doSomething();
zerarX(x1); //Não funciona
Como x é uma nova referência, o objeto recebido (new Xis()) será criado e alterará essa referência. x1, do lado de fora da função, continua apontando para o mesmo lugar.
O correto, seria fazer assim:
public void zerarX(Xis x) {
x.clear(); //Ok
}
Por outro lado, o C++ suporta uma construção de const. Isso deixa que você torne praticamente qualquer classe imutável, só dizendo que o objeto recebido é constante. Por exemplo:
UmaClasse::umMetodo(const std::vector& umaLista) {
umaLista.push_back(10); //Erro, umaLista aqui é const, então é imutável.
}
O que é, de fato, muito mais seguro que no Java (embora dê mais trabalho para se programar corretamente).