Curiosidade

Olá a todos os membros primeiramente,

existe uma diferença entre os seguintes trechos de código?


double total = 0;

for(Objeto objeto: listaObjetos) {

double valor = objeto.getValor();

total = total + valor;

}

e


double total = 0;
double valor;

for(Objeto objeto: listaObjetos) {

valor = objeto.getValor();

total = total + valor;

}

Note que apenas o q muda é o double valor… no primeiro caso ele ta dentro do laço e no segundo caso ele é apenas declarado antes.

Existe alguma diferença quanto a isso?

Me falaram uma vez que a diferença seria que o código de cima ocupa mais memória… é verdadeiro isso?

Obrigado a todos.

Quantidade de memória ocupada vai ser a mesma nos dois casos.

A questão chave é o escopo das variáveis que difere nos casos…

No primeiro trecho você declara a variável valor dentro do loop for, ou seja, ela só vai existir enquanto este loop estiver rodando. Assim que o for acabar, essa variável morre junto com ele.

Já no segundo caso você declarou ela antes do for e portanto, ela continuará existindo após o for terminar.

E quanto a sua dúvida de memória, a quantidade de memória ocupada será a mesma, a única diferença é que no primeiro trecho a memória que a variável valor está ocupando vai ser liberada. No segundo caso essa porção de memória continuará alocada enquanto o objeto em que esse atributo se insere tiver uma referência válida…

[quote=Ruttmann]Quantidade de memória ocupada vai ser a mesma nos dois casos.

A questão chave é o escopo das variáveis que difere nos casos…

No primeiro trecho você declara a variável valor dentro do loop for, ou seja, ela só vai existir enquanto este loop estiver rodando. Assim que o for acabar, essa variável morre junto com ele.

Já no segundo caso você declarou ela antes do for e portanto, ela continuará existindo após o for terminar.

E quanto a sua dúvida de memória, a quantidade de memória ocupada será a mesma, a única diferença é que no primeiro trecho a memória que a variável valor está ocupando vai ser liberada. No segundo caso essa porção de memória continuará alocada enquanto o objeto em que esse atributo se insere tiver uma referência válida…[/quote]

Acho que os resultados também seriam diferentes, não?

Já que a cada loop do foreach ele declara a variavel valor novamente.

==============================================================
Revendo aqui, vi que não faria diferença nesse caso. já que ele só recupera o objeto e soma seu conteudo ao total.

Já explicaram tudo =]

E sim, são diferentes, mas os códigos se equivalem quanto ao resultado, eu acredito que é uma boa prática nesse contexto do código você declarar a variável no foreach, pois, liberará espaço(mais cedo) e te dará a liberdade de declarar outra variável com esse mesmo nome.

Não digo isso tanto pelo nome, mas se dependendo do tamanho do método(não do foreach), pode ser um disperdicío de memória, imagine você se acostumar com essa prática e então começar a desenvolver aplicativos para celular(memória extremamente limitada), não seria uma boa prática de forma alguma.

Espero ter tirado alguma dúvida. Bye =]

[quote=Vynko]Já explicaram tudo =]

E sim, são diferentes, mas os códigos se equivalem quanto ao resultado, eu acredito que é uma boa prática nesse contexto do código você declarar a variável no foreach, pois, liberará espaço(mais cedo) e te dará a liberdade de declarar outra variável com esse mesmo nome.

Não digo isso tanto pelo nome, mas se dependendo do tamanho do método(não do foreach), pode ser um disperdicío de memória, imagine você se acostumar com essa prática e então começar a desenvolver aplicativos para celular(memória extremamente limitada), não seria uma boa prática de forma alguma.

Espero ter tirado alguma dúvida. Bye =] [/quote]

Isso depende muito do contexto da aplicação. Não dá pra saber se a variável valor é atributo de classe, ou uma simples variável auxiliar dentro do forEach

[quote=Vynko]Já explicaram tudo =]

E sim, são diferentes, mas os códigos se equivalem quanto ao resultado, eu acredito que é uma boa prática nesse contexto do código você declarar a variável no foreach, pois, liberará espaço(mais cedo) e te dará a liberdade de declarar outra variável com esse mesmo nome.

Não digo isso tanto pelo nome, mas se dependendo do tamanho do método(não do foreach), pode ser um disperdicío de memória, imagine você se acostumar com essa prática e então começar a desenvolver aplicativos para celular(memória extremamente limitada), não seria uma boa prática de forma alguma.

Espero ter tirado alguma dúvida. Bye =] [/quote]
Como você não sabe quando o GarbageCollector irá executar a coleção dos objetos que foram referenciados pela variável dentro do for, digo que isso é impossível dizer. Pode ser imediatamente após o laço ser concluído como pode demorar até o programa ser finalizado.
No primeiro caso, como a referência da variável é “apontada” a um novo objeto, a impressão é de que seja diferente, mas, na prática, somente o último objeto impede que esta seja destruída após término do laço for.

Obrigado a todos novamente…
é que grilaram comigo pq eu declaro dentro do laço…

quanto ao escopo… nesse caso nao importa para mim… a minha duvida mesmo era a questao de memoria… pq eu achei mto estranho ao dizerem que a forma de declarar dentro do laço é mais oneroso -.-’.

Só para esclarecer… quanto a consumo de memória não há diferença. Pelo código dá para ver que ambas são variáveis locais, portanto nenhuma delas vai ficar viva junto com o objeto; como é um tipo primitivo então provavelmente a memória vai ser alocada no próprio stack, sendo liberada ao final do método.

Embora a memória não seja liberada (e convenhamos, quem se importa com a memória que ocupa uma única variável double? hehe) o que falaram está correto: a variável de dentro do loop sai de escopo mais cedo, deixa de existir. Isso é uma boa prática pois deixa bem claro a finalidade da variável e o tempo de vida que vc espera que ela tenha, o que colabora com a legibilidade do código; e como um bônus, vc ainda pode reaproveitar o nome depois (como também já disseram).

Então em questões de desempenho ambas as maneiras são semelhantes, mas a qualidade do seu código será melhor declarando dentro do loop.

[quote=diegomadson]a minha duvida mesmo era a questao de memoria… pq eu achei mto estranho ao dizerem que a forma de declarar dentro do laço é mais oneroso -.-’.[/quote]Isso é uma lenda urbana propagada por quem começou a programar em Cobol… eles acham que declarar variáveis junto com a lógica é uma aberração :slight_smile:

[quote=gomesrod]Só para esclarecer… quanto a consumo de memória não há diferença. Pelo código dá para ver que ambas são variáveis locais, portanto nenhuma delas vai ficar viva junto com o objeto; como é um tipo primitivo então provavelmente a memória vai ser alocada no próprio stack, sendo liberada ao final do método.

Embora a memória não seja liberada (e convenhamos, quem se importa com a memória que ocupa uma única variável double? hehe) o que falaram está correto: a variável de dentro do loop sai de escopo mais cedo, deixa de existir. Isso é uma boa prática pois deixa bem claro a finalidade da variável e o tempo de vida que vc espera que ela tenha, o que colabora com a legibilidade do código; e como um bônus, vc ainda pode reaproveitar o nome depois (como também já disseram).

Então em questões de desempenho ambas as maneiras são semelhantes, mas a qualidade do seu código será melhor declarando dentro do loop.

Além do mais, a época de preocupar-se com bits a mais ou a menos de memória já passou (salvo se você desenvolve com JME)