Referencia em java

vamo discutir… (só um pouco)

No cod abaixo vceis podem ver que não é passado a referencia, e sim uma copia.

 public static void main( String [] args ) { 
  
    Object o = new String( "aaa" ); 
    f( o ); 
    System.out.println( o.toString() ); // ja aviso q a saida será "aaa"... 
 } 
  
 public static void f( Object o ) { 
  
    o = new String( "bbb" ); 
 } 

Baum, a classe String é algo aparte… só ela pra acontecer oq acontece com o codigo ai em cima.

já usando outra classe qualquer, é passado por referencia…

[code]
public class Teste {

public Teste() {
	MyVO myVO = new MyVO();
	vamoVe(myVO);
	System.out.println(myVO.getI() + myVO.getS()); 
                            //imprime "2mudou?"
}

private void vamoVe(MyVO myVO) {
	myVO.setI(2);
	myVO.setS("mudou?");
}

public static void main(String[] args) {
	new Teste();
}

}

class MyVO {

int i = 0;
String s = "abc";


public int getI() {
	return i;
}

public void setI(int i) {
	this.i = i;
}

public String getS() {
	return s;
}

public void setS(String s) {
	this.s = s;
}

}[/code]

pow, é assim msm?!? A classe String é a metida a diferente? ou tem varias mais classes assim?

O que acontece é o seguinte

As variáveis de tipos básicos são sempre passadas por valor.
As referências a classes são sempre passadas por referência (pode ver o nome ó: referências… passadas por referência!).

É razoável pensar assim, imagina que vc tem um vetor de trocentas posições. Se referências fossem passadas por valor, toda vez que você chamasse um método que recebe um vetor como parâmetro, aquele vetor seria inteiramente copiado na memória.

A classe String é uma classe especial, embora não seja, ela é tratada como tipo básico.
Pode ver que você não precisa inicializar Strings com new, pode simplesmente fazer

String s = “uma string”;

Da mesma forma, referências String são passadas por valor.

Desculpa se falei merda :slight_smile:

[quote=“luizfar”]O que acontece é o seguinte

As variáveis de tipos básicos são sempre passadas por valor.
As referências a classes são sempre passadas por referência (pode ver o nome ó: referências… passadas por referência!).

É razoável pensar assim, imagina que vc tem um vetor de trocentas posições. Se referências fossem passadas por valor, toda vez que você chamasse um método que recebe um vetor como parâmetro, aquele vetor seria inteiramente copiado na memória.

A classe String é uma classe especial, embora não seja, ela é tratada como tipo básico.
Pode ver que você não precisa inicializar Strings com new, pode simplesmente fazer

String s = “uma string”;

Da mesma forma, referências String são passadas por valor.

Desculpa se falei merda :)[/quote]

CONCORDO plenamente… todos Objects são passados por referencia, exceto nossa amiga String. Já todos primitivos são passados por valor :slight_smile: :slight_smile: . Onde eu quero chegar, é só a String que é assim ou existe outras?

Tudo em java é passado por valor. Teve um tópico q respondi com exemplos direitinho, mas faz tempo e não consegui encontrar ele agora… :sad:

matheus, por favor me explica direito isso q eu to por fora do topico…
vc ta dizendo que java nao tem a principal vantagem de programacao orientada a objetos, que eh a passagem por referencia??
nao ententi bem… :sad:

espero resposta

matheus, por favor me explica direito isso q eu to por fora do topico…
vc ta dizendo que java nao tem a principal vantagem de programacao orientada a objetos, que eh a passagem por referencia??
nao ententi bem… :sad:

espero resposta[/quote]

passagem por referencia ser a principal vantagem da OO? Quem te disse esse absurdo? heheheh… cara, agora to indo deitar hehehe, amanha eu posto exemplos disso (se ninguem o fizer até lá)

opa, voltei pra dar o ex. q prometi :slight_smile: , veja:

class Foo {

   void doStuff( Object o ) {

      o = new String( "def" );
   }

   public static void main() {

      Foo f = new Foo();

      String s = "abc";
      doStuff( s );

      System.out.println( s ); // qual será a saída? :)
   }
}

bem, se a passagem é por referencia, então a saída do println() deve ser “def”… oq não ocorre, o valor do objeto continua sendo “abc” :slight_smile: . Vamos a uma explicação…

bem, oq é exatamente uma referencia a um objeto? veja bem, com tipos de dados primitivos, qnd nos declaramos um int, estamos armazenando uma posição de memoria no tamanho de um int, e atribuindo um nome para essa posição, ok… ai a passagem é por cópia, isso é entendido certo? … agora, qnd nos declaramos uma referencia a um objeto, estamos criando um ponteiro para uma área de memória onde esse objeto realmente reside. Essa referencia tem um nome tb, e uma posição de memória tb, na memória seria algo do tipo:

--------------------------------------
| referencia s                       |
--------------------------------------
| endereço da referencia: x0001      |  
| endereço do objeto apontado: x0020 |
--------------------------------------

-----------------------------
| objeto real na memoria    |
-----------------------------
| endereço do objeto: x0020 | 
-----------------------------

ok, espero q tenha entendido como fica, heheahea, agora, qnd a gente passa uma referencia a um objeto como parametro de um método, na verdade estamos passando uma cópia dessa referencia, ou seja, vai ser passado uma outra variável de referencia, com um outro endereço, mas apontando para o mesmo objeto! No código de exemplo, quando o objeto “o” recebe uma nova String, ele nao esta alterando o valor apontando pela referencia “s” q vem pelo parametro, pq originalmente ela tem o seu proprio endereço, e aponta para “abc”, e o objeto “o” é uma OUTRA referencia para esse mesmo objeto, q esta passando a apontar para outro objeto, no caso “def”… era isso :slight_smile:

e imagine se TODO objeto fosse realmente passando “por referencia” mesmo (o mesmo conceito de C), onde um ponteiro realmente altera o conteúdo do outro, ja imaginou q terrível fazer um código como esse!?

class Bar {

   private String s = "abc";

   public String getS() { return s; }
}

class Test {

   public Test () {

      Bar b = new Bar();

      String s = b.getS();

      s = new String( "def" ); // vc estaria alterando o valor real do objeto privado de Bar!!!!!!!!
   }
}

Acho que o problema é aqui é definir passagem por referência e por valor, parece que cada um tem sua definição disso.

Bom, tudo é passado por valor mesmo, é verdade, mas são passadas referências, entao, de uma certa forma, na prática, você passa por referência.

O que isso quer dizer? Quer dizer q se vc tem uma classe:

class Numero
{
  private int numero;
  public Numero(int n)
  {  numero = n; }

  public void setaNumero(int n)
  {  numero = n; }

  public String toString()
  { return Integer.toString(numero); }
}

e instanciá-la e passá-la para um método, assim:

class Teste
{
  private Numero num;

  public Teste()
  {
    num = new Numero(2);
    modifica(num);
    System.out.println(num.toString()); //vai escrever 5
    naoModifica(num);
    System.out.println(num.toString()); //vai escrever 5 tb
  } 

  public void modifica(Numero n)
  {
     n.setaNumero(5);
  }

  public void naoModifica(Numero n)
  {
    n = new Numero(6);
  }

  public static void main(String args[])
  {
    new Teste();
  }
}

O método modifica(Numero n) modifica a o valor para onde a referência aponta. Isso, em C/C++ é uma típica passagem por referência.

Já o método naoModifica(Numero n) não modifica, pois altera a referência passada, e não o valor que ela referencia.

:slight_smile:

[quote=“luizfar”]
O método modifica(Numero n) modifica a o valor para onde a referência aponta. Isso, em C/C++ é uma típica passagem por referência.

Já o método naoModifica(Numero n) não modifica, pois altera a referência passada, e não o valor que ela referencia.

:)[/quote]

Sim exatamente, isso pq o objeto no parametro do método é um ponteiro pra mesma área de memória q o objeto q vem na referencia :joia: