Monday, June 11, 2007

Tutorial[parte5repost]

3.2-Passagens de Parâmetro em Java:


Existe um mito em Java que precisa ser esclarecido:
-Objetos são passados por referência, tipos primitivos são passados por valor.Certo?ERRADO!Todos os parâmetros em Java são passados por valor, a diferença é que, no caso de objetos, são passados referências a esses objetos, nunca os próprios objetos! Deve ser observado que os valores das variáveis são sempre primitivos ou referências a objetos, jamais os objetos propriamente ditos!Vamos a exemplos práticos :

public class Parametros{
 
        
  public static void main(String []args){
         int y=0;
         Object x=null;
            tipoPrimitivo(y);
            tipoReferencia(x);   
         System.out.println(y); 
         System.out.println(x);                          
                                           } 
  public static int tipoPrimitivo(int parametro){
            parametro=30*10;
     return parametro; 
                                        }
  public static Object tipoReferencia(Object o){
          String a= "GUJ"; 
        o=a; /*NOTA:atribuição permitida pois
               String também é um Object(todas
               as classes extendem java.lang.Object).
               Poderia ser executada a atribuição o="GUJ"
               diretamente sem problemas. */
     return o;
                                                }                                

} //fim da classe Parametros

Compile e rode.(javac Parametros.java e java Parametros )

Reparou na tela?Veja:

0
null


E não:

300
GUJ

Porque? Porque na chamada a tipoPrimitivo(y); uma cópia do valor inicial da variável (0) é passado como parâmetro ao método, não a variável em si, quando esse método termina, a variável permanece inalterada, o mesmo vale para a chamada a tipoReferencia(x) , pois uma cópia da variável é passada, não a própria! É o mesmo tipo de cópia que acontece quando fazemos uma instrução de atribuição a uma variável!Jamais será passado a própria variável ao método, pois se fosse possível fazê-lo em Java, seu conteúdo seria modificado e isso caracterizaria uma passagem por referência! Na próxima seção veremos mais sobre esse assunto e alguns erros que devemos evitar programando!

2 comments:

Alexandre Ferreira said...

Cara você está fazendo confusão.
Veja bem, as classes Wrapper(Integer, Double,Float, Void e etc...), a Classe String e a Classe Object.
Elas sao passadas por valores, pois assim quebraria muita coisa em java, como segurança nas senhas e etc...
(Não vou da outros exemplos para não sair do topico).

Agora suas classes são passadas por referencias sim!!!
Veja, usando seu código:
public class Parametros {

public static void main(String[] args) {
Pessoa p = new Pessoa();
p.setNome("Vai mudar!");
tipoReferenciaPessoa(p);
System.out.println(p.getNome());
}

private static String tipoReferenciaPessoa(Pessoa p) {
p.setNome("Mudou: Alexandre Silva [ AFSRJ - GUJ]");
return p.toString();
}

Veja o resultado:
Se o que você falou fosse verdade o resultado seria:
Vai mudar!
Mais como a referencia existe!!!
O resultado é:
Mudou: Alexandre Silva [ AFSRJ - GUJ]

Ironlynx said...

Alexandre, desculpe responder tãao tarde, mas eu mesmo quase não entro aqui, esse blog é mais um repositório de velharias(esse artigo é de 2004 quando li a JLS), do que um blog mesmo.

Agora vamos ao seu post:
Eu tinha que ter explicadomelhor, dei vacilo nessa.
A variável que vc passou(por valor) um "tipo referência" dentro tipoReferenciaPessoa() muda a referencia ao atributo nome do objeto Pessoa, mas que NÂO muda o MESMO objeto String,pois sempre que vc mexe numa String, um novo objeto é criado.Strings são imutáveis(Tá, com Reflection não existe essa imutabilidade, mas é covardia...)O erro nesse exemplo é ter usado um tipo de retorno.Compliquei á toa...RSRS..
Leia aqui:
http://www.guj.com.br/posts/list/24894.java
e Aqui(esse tuto melhor formatado):
http://www.guj.com.br/posts/list/19722.java