Java 7: Try-with-resources ou Automatic Resource Management

Legal…

Acho que no caso de ter muitas instruções intermediárias, seria melhor usar o try…with aninhado.

O C# aceitava apenas uma declaração no “using”, portanto é necessário fazer o equivalente do try aninhado (um monte de ‘usings’ aninhados). Isso é um porre (não sei se acertaram isso no c# 4.0)

No Java eles aprenderam a lição e é por isso que é possível declarar tudo que é necessário dentro dos parênteses de um único ‘try’.

[quote=Felagund][quote=marcosalex]Está acontecendo com o Java e C# o mesmo que aconteceu com o Delphi e VB: a MS lança uns recursos que atendem 0,001% de melhoria na produtividade e sai com um marketing de que possui o recurso e o outro não. Daí a outra empresa corre e implementa também, mesmo que na prática pouquíssima gente vai usar e que ajuda muito pouco no produto final.

Chega uma hora que as duas linguagens vão ficar tão cheias de recursos quase inúteis que vão ficar pesadonas, enormes e confusas, gerando códigos idem. Até que surja uma nova onda e comece tudo de novo.[/quote]

É o ciclo da vida :)[/quote]

É, Rei Leão é da hora.

Acho que só pelo fato de que programadores inexperientes vão começar a fechar recursos corretamente já é um grande avanço.
Esse é um sintax suggar bastante significativo, como foi a inclusão do for each.

Não se trata apenas de um recurso estético, mas de uma forma de fornecer de maneira conveniente o tratamento correto.

Ah, entanglement, o C# já suportava multiplas inicializações no using, separadas por vírgula:
http://msdn.microsoft.com/en-us/library/yh598w02.aspx#Y220

Discordo fortemente de quem se refere isso a um recurso motivado pelo marketing.
Automatic Resource Management é um conceito bastante antigo, já surgido no C++ com o nome de RAII.

A técnica só obteve uma sintaxe mais limpa e elegante em C#, devido as características da linguagem, e agora o recurso vem para o Java.

Olhei a mais nova especificação da linguagem C# e ela diz que você pode ter várias inicializações, mas todas as variáveis têm de ser do mesmo tipo - ou seja, não dá para escrever o estrito equivalente do novo recurso do Java sem usar usings aninhados.

using (X x = new X(), y = new X(), z = new X()) 
{
    ...
}

O C# não força que você tenha de fazer uma declaração (como é o caso do Java); aceita expressões também. A expressão cria implicitamente uma variável local com o tipo de retorno da expressão (que pode ser bastante complexo, por sinal - veja o LINQ para ver como é possível criar tipos arbitrariamente complexos em C#); essa variável local “escondida” irá ter uma referência a esse objeto, que poderá ser fechado (“Dispose”) etc.

      using (new Y()) 
      {
          ...
      }

[quote=ViniGodoy]
Discordo fortemente de quem se refere isso a um recurso motivado pelo marketing.
Automatic Resource Management é um conceito bastante antigo, já surgido no C++ com o nome de RAII. [/quote]

Desnecessário dizer que Lisp tem isso desde antes do C++ existir.

Em Lisp a macro with-open-file já fecha o stream automaticamente, seja de forma normal ou por erro. Além das macros padrões, o desenvolvedor pode criar as suas próprias sintaxes para o que bem entender.

C++, assim como Java ou C#, não inventou nada.

http://www.paulgraham.com/icad.html

Não disse que o C++ estava inventando qualquer coisa. Disse que no C++, esse conceito surgiu com o nome de RAII, mas o conceito em si, não é invenção do C++, ou mesmo do LISP.
Estava apenas mostrando que no C++ esse conceito era usado, e foi extremamente fortificado, ao ponto de ser considerado um padrão.
E que a inserção dele no Java não se trata apenas de um syntax suggar, mas a fortificação de um detalhe bastante importante para justifica-lo.

O próprio Java já possuia APIs que implementavam o conceito (como as APIs de banco de dados do Spring).
Mas essa é uma sinalização clara, de que isso é importante, ao ponto de incluirem para isso um comando na linguagem, que certamente será cobrado dos desenvolvedores aspirando por uma certificação.

Acho extremamente válido que o Java também tenha colocado em sua linguagem estruturas próprias que demonstram essa preocupação em fechar recursos.
E que o conceito de automatic resource management tenha surgido no vocabulário “javanês” à partir de agora.

[quote=diego_qmota]Eu posso fazer assim no JAVA 7?

int codCadastro = 345;

try (Connection con = ConnectionFactory.getNewConnection();
      PreparedStatement ps;
      ResultSet rs; ) {

      String sql = "select * from cadastro where id = ?";
      ps = con.prepareStatement(sql);
      ps.setInteger(1, codCadastro);
      rs = ps.executeQuery();

      if (rs.next()) {
          //....
   
      }


} catch (Exception e) {
}

Ou seja, declarar objetos que quero fechar no try, sem inicializá-los dentro do mesmo? (vide os objetos rs e ps).
Gostaria de saber porquê eu acabo setando os demais objetos dentro do try…[/quote]
Se não me engano, tem que ficar tudo dentro do try nesse caso.

EDIT:
diego_qmota criou o tópico http://www.guj.com.br/java/250876-bloco-trywith-do-java-7