12 de março de 2007

Passagem de parâmetros em Java, valor ou referência?

Passagem de parâmetros em Java é por valor ou referência? Eu sei que é um assunto meio batido, mas ainda assim gerou muita conversa e discussão entre os mestrandos e doutorandos aqui do grupo de computação gráfica da UFRGS. Vamos aos fatos!

Java possui dois tipos de dados,

Tipo primitivo:
Englobam os tipos numéricos (byte, short, int, long, char, float, double) e booleano (boolean). Uma variável de tipo primitivo recebe um valor primitivo, este valor é armazenado diretamente no espaço de memória alocado para a variável. Exemplo:
public static void main(String[] args) {
byte a = 10;
byte b = a;
}
A figura ao lado representa as duas áreas de memória alocadas para as variáveis a e b, cada uma mantendo o seu respectivo valor.


Tipo referência:
englobam os tipos classes, interfaces e arrays. Salientando que uma String é uma classe. Uma variável do tipo referência recebe como valor uma referência para um objeto. Na área de memória da variável é armazenado um ponteiro para a área de memória que está o objeto. Objeto é uma instância de classe ou array. Exemplo:
public static void main(String[] args) {
Carro a = new Carro();
Carro b = a;

}
Figura apresenta a área de memória alocada para o objeto Carro e as duas áreas de memória alocadas para as variáveis a e b. Notem que as duas variáveis possuem áreas de memórias distintas, mas que referenciam o mesmo objeto.



Concluindo, passagem de parâmetro em Java é SEMPRE POR VALOR, isto é, ao passar uma variável como parâmetro de um método sempre será efetuada a cópia dos bits desta variável,

Variável primitiva:
public static void main(String[] args) {
byte preco = 10;
System.out.println("Preço antes : " + preco);
// Saída "Preço antes : 10"

somaPreco(preco);
System.out.println("Preço depois: " + preco);
// Saída "Preço depois: 10"

}

private static void somaPreco(byte parametro) {
parametro += 5;
}
Notamos que o conteúdo da variável preco foi copiado para a variável parametro, portanto quando somamos 5 a variável parametro estamos alterando apenas o conteúdo desta variável, enquanto a variável numero permanece com o mesmo valor.


Variável referência:
public static void main(String[] args) {
Carro carro = new Carro();
carro.preco = 10;
System.out.println("Preço antes : " + carro.preco);
// Saída "Preço antes : 10"
somaPreco(carro);
System.out.println("Preço depois: " + carro.preco);
// Saída "Preço depois: 10"
}

private static void somaPreco(Carro parametro) {
parametro = null;
}

private static class Carro {
byte preco;
}
Aqui o conteúdo da variável carro é passado para a variável parametro, ou seja, uma cópia da referência para o objeto Carro, as duas variáveis apontam para o mesmo objeto. Quando alteramos o conteúdo da variável parametro para null, a variável carro permanece inalterada.


Talvez a dúvida da galera tenha ocorrido pela maioria ser desenvolvedor C++, onde o tipo referência tem uma conotação um pouco diferente.

A regra de passagem por valor pode ser generalizada para qualquer atribuição, passagem de parâmetro ou retorno de método em Java, sempre é feita a cópia dos bits da variável, ou seja, SEMPRE POR VALOR.

Referência: Java Language Specification

5 de março de 2007

Tempo, nosso bem mais precioso.

Falar da correria do final de semestre foi proposital no último post. O final de semestre me encanta, me fascina, me transforma, me sinto um gênio, um homem com sua cópia!

Nesta época ando a passos largos, faço 10 coisas ao mesmo tempo, termino 10 coisas ao mesmo tempo, se bobear, as 10 no mesmo dia. Nesta época as prioridades ficam claras, as necessidades evidentes, os prazos não passam de poucas horas, as decisões sempre certeiras. A cada dia uma nova batalha travada, uma nova batalha vencida, sem aquela sensação de não ter evoluído nada.

De onde sai toda esta produtividade? Tentei relembrar e listar algumas atitudes tomadas no final de semestre:
  • listar tarefas: nesta lista vão todas as tarefas a serem desenvolvidas nesta época;
  • estabelecer prazos: definir um tempo para o término de cada tarefa, seja arrojado nos seus prazos, isso fará a diferença;
  • priorizar: estabelecer uma ordem para as tarefas, geralmente as que oferecem maior risco têm maior prioridade;
  • tarefas diárias: listar em um papel as suas atividades do dia, mas tem que ser em papel, aquela história de todo list na internet não funciona;
  • focar: talvez seja a mais importante das atitudes, manter o foco nas tarefas que estão na sua lista do dia, nestas tarefas desenvolver apenas o necessário, para que o prazo arrojado seja alcançado;
  • focar: estou batendo nesta tecla novamente devido a sua importância, tente não mudar o seu contexto de trabalho, iniciou uma tarefa, continue nela até terminar;
Escrevi sobre isso porque estou me sentindo improdutivo no mestrado. Durante o post fui me deparando com vários erros que estou cometendo:
  • Não estou fazendo minha lista diária de tarefas. Como vou saber se alcancei meus objetivos do dia?
  • Estou trocando de contexto direto. Estou lendo um artigo, dai vejo uma referência, parto a procura desta referência, depois tento implementá-la. Cadê o foco Giovane?
  • Não estou dando prazo para as minhas tarefas. Pior situação que pode existir, você fazer algo que tenha tempo ilimitado. XP já dizia: "Se tiveres 8 horas para fazer algo, você vai usar as 8 horas. Se tiveres 16 horas para fazer a mesma coisa, você vai usar as 16 horas."
Uma coisa é certa, vou ser um guerreiro de final de semestre o ano todo. Não é pelo meu chefe, não é pelo prêmio de melhor do mês, não é por ninguém além de mim. Quero evoluir diariamente, quero fazer a diferença, para isto, quero cuidar do meu bem mais precioso, quero que isso faça parte da minha cultura!

E você como tem cuidado do seu bem mais precioso?
Continuas escondido nas estimativas de 16 horas para aqueles relatórios que consegues fazer em 8 horas? Continuas nos fóruns da vida e indo para casa com a sensação de nada feito?
Se não, me conte como mantém a sua produtividade!