Ponteiros não existem em Java, mas o que esta acontecendo no meu código?

10 respostas
Tsunami1

Galera, estou vindo de C e pelo que percebi ao estudar Java é que não se usa ponteiros (o java usa mas não deixa que o programador se estresse com esses assuntos)
Sei também que se passarmos um vetor como parametro para um metodo, modificar dentro do metodo esse vetor, o vetor será modificado como se estivesse sido passado um ponteiro…
Porém no meu código não está mudando esse vetor, estou passando o parametro para um metodo de outra classe…

Exemplo:

Object[][] data;
ClasseQualquer.mudaVetor(data);

e agora dentro da classe “ClasseQualquer”:

public void mudaVetor(Object[][] vetor)
{
	Object[][] vetor = new Object[5][3];
	// ...
	// vou botando os valores no vetor recebido...
	//...
}

O que está acontecendo é que esse “data” depois de ter sido passado como parametro para o CalsseQualquer.mudaVetor() continua sem ter nada dentro (inclusive acho que não foi nem inicializado).
Não sei se o erro é pq eu estou inicializando ele dentro do mudaVetor()… ou sei lá… preciso de uma luz de vcs nisso aqui!!!

Origado!!!

10 Respostas

peczenyj

Vc pode fazer isso:

class MinhaClasse{ public void alteraObjeto(Objeto meuObjeto){ meuObjeto.algumMetodoQueRealizaAlteracoes("lalala"); meuObjeto = new OutraCoisa(); /* a partir de agora, meuObjeto é referencia para outra coisa... não afeta o objeto passado como parametro para esse metodo */ } }

saninaimayer

Primeiramente, esse seu código não ta dando erro por causa que você está declanrando novamente a variável passada como parâmentro?

Segundo, estou vendo que toda vez vc ta inicializando um novo objeto quando vc executa o método, então sempre será inicializado e mostrará vazio. Inicialize o objeto fora do método e teste novamente.

saninaimayer

Ahh e mais uma coisa, ponteiros existem no java sim eles só não são explicitos como no C++.

douglas_vidotto

Em java, todos os valores são passados por cópia nos métodos(ou funções no caso do C). No caso de objetos e arrays, voce passa uma cópia da referência para a função, ou seja, uma cópia do “ponteiro” para dentro da função. No seu caso você cria um array bidimensional chamado data que não aponta para nada, ou seja, você não iniciou o array, portanto ele possui null de início. Aí, ao chamar a função que deveria mudar o array, você passa uma cópia da referencia, ou seja null, e inicia um array chamado “vetor” com null. Depois, “vetor” é iniciado com 15 posições de memória (new Object[5][3];).

Se “data” apontasse para algum local de memória e fosse passada sua referencia na função, o local de memória para onde essa referencia apontava ia ser modificado, e consequentemente, a variável data também ia. Mas como ele apontava para nada(null) de início, não houve oque modificar para ESSA variável, e assim, ela continuou “vazia”. Para não ocorrer esse erro você deve primeiro iniciar o array “data”, e depois passar como referencia para algum método.

acho que é isso,

Abraços!

ViniGodoy

Mas daí foge a definição de ponteiro. A definição é:
Ponteiro: Uma varíavel cujo valor representa um endereço de memória.

Como nenhuma variável no java representa o endereço, mas sim o objeto em si, Java tem o conceito de referência, não de ponteiro.

D

Pelo que eu pude intender da explicacao acima, o que esta acontecendo e o seguinte:

Voce inicia uma variavel do tipo array. Sem valor algum, sem instanciar lugar nenhum. Depois passa como parametro para o metodo esse “nada” e dentro do metodo voce instancia o vetor com 5 e 3 posicoes. Ai pode comecar a mudar os valores e tals. Mas por ter cido instanciado dentro de um metodo, é uma variavel temporaria e depois que o metodo terminar, a referencia vai ser apagada tmb. Certo?

Outra duvida:
Eu ja vi esse Object algumas vezes. Isso e uma classe criada pelo altor do codigo ou é algo do java mesmo?

Tsunami1

Obrigado pela ajuda de vcs, já consegui fz o que queria… Tive que tirar o void e retornar o object…

Object[][] vetor;
Object[][] = ClasseQualquer.mudaVetor(vetor);
public Object[][] mudaVetor(Object[][] vetor)
{
// (...) faz as operações necessárias como inicializar com a quantidade de posições que eu quero e etc...
return vetor;
}

Obrigadão pessoal!!!

ViniGodoy

É do Java. Object é a classe base de todas as classes, declare você um “extends Object” ou não.
O autor só usa isso para dizer que a variável pode receber absolutamente qualquer objeto.

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:

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.

Quase, porque existem sacanagens tb… :slight_smile:

ViniGodoy
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).

Criado 3 de novembro de 2008
Ultima resposta 5 de nov. de 2008
Respostas 10
Participantes 7