Novidades do Java 7

Depois de um longo tempo de espera, em Julho de 2011 foi lançado oficialmente o Java 7. Houve algumas atualizações referentes as versões mais antigas do Java, com a introdução de algumas funcionalidades novas que estão listadas abaixo:

  • Strings in Switch
  • Multi-Catch Similar Exceptions
  • Try-with-resources Statement
  • Binary Literals
  • Underscore Between Literals
  • Simplified Generics – Diamond Syntax
  • Simplified Varargs Method Invocation

Esta nova versão já está disponível para download na página da Oracle. Algumas IDE’s como Netbeans 7.0 e Intellij IDEA 10.5 já possuem suporte nativo para a versão 7 do Java. Neste tutorial vou demonstrar quais as novidades presentes até o momento nessa nova versão.

O que há de novo no Java SE 7?
O Java SE 7 é a última versão para Java que contém muitos recursos novos, melhorias e correções de bug para melhorar a eficiência para desenvolver e executar os programas Java. Aqui está um breve resumo das melhorias incluídas com a versão Java SE 7:

  • Desempenho, estabilidade e segurança melhorados.
  • Melhorias no Java Plug-in para desenvolvimento e implantação dos Aplicativos Rich Internet.
  • Melhorias na linguagem de programação do Java que permite aos desenvolvedores gravar e otimizar o código Java do facilidade.
  • Melhorias na máquina virtual do Java para suportar as linguagens não Java.

Fonte: http://www.java.com/pt_BR/download/faq/java7.xml

1. Strings in Switch

Até a versão 6 do Java quando utilizado um teste no bloco Switch/Case, era apenas possível utilizar tipos como byte, char, short ou int. A partir da versão 7, será possível usar o tipo String, o que muitos programadores não entendiam por que não era permitido nas versões anteriores (Listagem 1).

Listagem 1. Switch/Case com String
public class HelloJava7 {
    public static void main(String[] args) {
        testSwitch();
    }

    private static void testSwitch() {
        String ide = "Idea";

        switch (ide) {
            case "Netbeans":
                System.out.println("IDE Netbeans");
                break;
            case "Eclipse":
                System.out.println("IDE Eclipse");
                break;
            case "Idea":
                System.out.println("IDE Intellij IDEA");
                break;
            default:
                System.out.println("Note Pad");
        }
    }
}

2. Multi-Catch Similar Exceptions

Outra novidade é parte de exceções. A possibilidade de criar um único bloco catch com varias exceções similares. No caso a similaridade deve ser o que elas irão exibir para o usuário, como por exemplo, um mesmo printStackTrace. Veja na Listagem 2 que quando utilizado o e.printStackTrace(); as exceções fazem parte do mesmo bloco catch, mas a exceção que utiliza e.getMessage(); ficou de fora desde bloco.

Listagem 2. Similar Exceptions
private static void testSimilarExceptions() {
	String url = "jdbc:derby:myDerby;user=derby;password=derby";
	String driver = "org.apache.derby.jdbc.EmbeddedDriver";

	//Até o Java 6
	try {
		Class.forName(driver); //-> ClassNotFoundException
		DriverManager.getConnection(url); //-> SQLException
		boolean file = new File("arq.txt").createNewFile(); //-> IOException
		DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		new Date(formatter.parse("05/08/2011").getTime());//-> ParseException
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	} catch (SQLException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} catch (ParseException e) {
		e.getMessage(); 
	}

	//Novidade Java 7
	try {
		Class.forName(driver);
		DriverManager.getConnection(url);
		boolean file = new File("arq.txt").createNewFile();
		DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		new Date(formatter.parse("05/08/2011").getTime());
	} catch (ClassNotFoundException | IOException | SQLException e) {
		e.printStackTrace();
	} catch (ParseException e) {
		e.getMessage(); 
	}
}

3. Try-with-resources Statement – Automatic Resource Management

Nesta novidade o Java 7 faz desnecessário o uso do bloco finally em um try/finally ou até mesmo em um try/catch/finally. Isto só é possível quando utilizado no bloco finally um objeto que implemente a interface Closeable, que por sua vez estende a interface AutoCloseable, veja na Listagem 3 um pequeno exemplo do uso desta novidade. No caso deste exemplo o bloco finally possui uma chamada ao método close() do objeto FileInputStream, por isso, é possível omitir o bloco finally. O próprio Java 7 reconhece que deve fechar o fluxo do objeto tanto em uma execução sem erros como em uma execução que gere alguma exceção.

Listagem 3. Omissão do bloco Finally
public static void testTryWithResources() throws IOException {
	//Até o Java 6
	FileInputStream in  = new FileInputStream("arquivo.txt");
	try {
		in.read();
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} finally {
		 in.close();
	}

	// Java 7
	try (FileInputStream ins = new FileInputStream("arquivo.txt")) {
		ins.read();
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}
}

Analisando a classe FileInputStream, pode se ver que ela estende a classe InputStream, que por sua vez implementa a interface Closeable que estende AutoCloseable. Até o Java 6 (doc: http://download.oracle.com/javase/6/docs/api/java/io/Closeable.html) a interface Closeable não possuía uma superclasse, já no Java 7 (doc: http://download.oracle.com/javase/7/docs/api/java/io/Closeable.html) a interface AutoCloseable foi criada para criar a possibilidade mostrada abaixo:

public class FileInputStream extends InputStream {...}
public abstract class InputStream implements Closeable {...}
public interface Closeable extends AutoCloseable {...}
public interface AutoCloseable {...}

4. Binary Literals

Ao contrário das versões anteriores do Java onde a representação dos números era restrito a decimal, octal e hexadecimal, o Java 7 introduz os recursos onde podemos criar números binários usando o prefixo 0b (zero b) e o sufixo será o próprio número binário. Na Listagem 4 vemos um exemplo onde é comparado o valor primitivo 12 com sua representação em binário, e o resultado deverá ser verdadeiro.

Listagem 4. Comparação entre numero e binário
public static void testBinaryIntegralLiterals() {
	int numero = 12;

	if (numero == 0b1100) {
		System.out.println(true);
	} else {
		System.out.println(false);
	}
}

5. Underscore Between Literals

Números longos eram difíceis de ler e o Java 7 tornou isto mais fácil. Agora você pode separá-los usando um sublinhado (underline/underscore), por exemplo, o número 1111111111 a primeira vista é difícil saber seu valor (1 bilhão). Utilizando o underscore a visualização fica mais clara 1_111_111_111 (Veja na Listagem 5).

Listagem 5. Usando underscore para separa números
private static void testUnderscore() {
	int v1 = 1_000_000;
	System.out.println("HelloJava7.v1: " + v1);

	long v2 = 1_111_111_111_111L;
	System.out.println("HelloJava7.v2: " + v2);

	Integer v3 = 1_000_000_000;
	System.out.println("HelloJava7.v3: " + v3);

	Long v4 = 2_211_211_211_211L;
	System.out.println("HelloJava7.v4: " + v4);

	System.out.println("HelloJava7.v5: " + 1_234_567_891_234_567_890L);
}

Não podemos fazer uso do underscore nos seguintes casos:

  • No início ou fim de um número: int valor = _99;
  • Junto (antes ou depois) com um ponto numa variável double/float: double valor = 0._99;
  • Junto (antes ou depois de um caractere declarativo (x, b ou l): int valor = 0b_00_1;

6. Simplified Generics – Diamond Syntax

Quando declaramos genéricos precisamos especificar o tipo que queremos (a classe que vamos usar) no lado esquerdo (da atribuição) e também no lado direito (da atribuição). Isso não será mais preciso, colocando os sinais de generics <> do lado direito automaticamente o compilador irá saber quais as classes que deve usar, no caso as mesmas que foram declaradas no lado esquerdo. Veja um exemplo na Listagem 6.

Listagem 6. Declarando listas com Java 7
private static void testDiamondSyntax() {
	//No Java 5 e 6
	List list = new ArrayList();
	//No Java 7
	List list7 = new ArrayList<>();

	//No Java 5 e 6
	Map map = new HashMap();
	//No Java 7
	Map map7 = new HashMap<>();
}

7. Simplified Varargs Method Invocation

Esta talvez seja a atualização mais complicada de se entender. Na verdade nada será alterado em relação ao código, como as anteriores, mas sim em relação a interpretação do compilador em um caso especifico que em versões anteriores geravam mensagens de aviso (warning).

Em Java arrays e tipos genéricos não se relacionam muito bem, veja o seguinte exemplo na Listagem 7. Este código quando compilado irá gerar a um Warning parecido com este “Note: HelloJava7Varargs.java uses unchecked or unsafe operations.”. Porém não existe nada de errado no código, ele compila e executa sem problemas, mas lança essa mensagem de aviso.

Listagem 7. Arrays e Generics
import java.util.*;

public class HelloJava7Varargs {
    public static void main(String[] args) {
        Set aSet = new HashSet();

        List> listOfSets = Arrays.asList(aSet);
    }
}

Na verdade, o que acontece é que antes de o compilador gerar o bytecode é feita uma conversão no programa que modifica a linha 7, que internamente passa a valer:

List> listOfSets = Arrays.asList(new Set[]{aSet});

Note que nessa conversão o Set usado para construir o array não contém mais a informação de tipo (em Java não é permitida a criação de um array usando generics) o que provoca o warning. Uma forma de evitar esse warning é incluindo a anotação @SuppressWarnings("unchecked") no método, ou na linha imediatamente antes daquela onde o compilador indicou o warning, (Listagem 8).

Listagem 8. Incluindo anotação @SuppressWarnings – Java 5/6
import java.util.*;

public class HelloJava7Varargs {
    @SuppressWarnings({"unchecked"})
    public static void main(String[] args) {
        Set aSet = new HashSet();

        List> listOfSets = Arrays.asList(aSet);
    }
}

No Java 7 esse problema foi solucionado e códigos compilados na nova versão não terão a mensagem de warning exibida sem a necessidade de usar a anotação @SuppressWarnings("unchecked").

Referências

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...