Melhorias no tratamento de Exceptions em Java 7

Post traduzido e adaptado do Forum da Oracle.
Texto original de Manfred Riem.

Saiba como aproveitar melhor o tratamento de exceções, uma de muitas mudanças úteis encontradas no Project Coin, em Java SE 7.

O Project Coin é um dos projetos que foram desenvolvidos para a implementação do Java 7. A ideia do projeto era adicionar pequenas mudanças na linguagem, sem a necessidade de depender de outros projetos do java 7, e sem forçar os desenvolvedores a aderirem à nova sintaxe.

Algumas das melhorias implementadas pelo Project Coin são:

  • String no uso de Switch
  • Melhorias na escrita de literais do tipo Integral (byte, short, int e long)
  • Multiplos Catch em Exception, tratados aqui
  • Definição de tipo melhorada para criação de instâncias genéricas (“diamond”)
  • Try-com-recursos, tratados aqui
  • Invocação simplificada do método varargs

Exceções com Multi-Catch

Exceções com Multi-Catch foram adicionadas ao Java SE 7 para mais fácil e mais conciso a captura de exceções. Veja abaixo como migrar o seu código de manipulação de exceções de um código pré-Java SE 7 para um código Java SE 7.

Exemplo 1:

public class ExampleExceptionHandling
{
   public static void main( String[] args )
   {
   	try {
   		URL url = new URL("http://www.yoursimpledate.server/");
   		BufferedReader reader = new
				BufferedReader(newInputStreamReader(url.openStream()));
   		String line = reader.readLine();
   		SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
   		Date date = format.parse(line);
   	}
   	catch(ParseException exception) {
   		// Capturando problemas de conversão de URL.
   	}
   	catch(IOException exception) {
   		// Capturando problemas de I/O.
   	}
   	catch(ParseException exception) {
   		// Capturando problemas de conversão de datas.
   	}
   }
}

No passado, se você quisesse ter a mesma lógica para tratar dois ou três casos de Exception, como por exemplo ParseException e IOException, você tinha que copiar e colar o mesmo código em ambos os blocos Catch. Um programador inexperiente ou preguiçoso poderia pensar que estaria tudo bem fazer o seguinte:

Exemplo 2:

public class ExampleExceptionHandlingLazy
{
   public static void main( String[] args )
   {
   	try {
   		URL url = new URL("http://www.yoursimpledate.server/");
   		BufferedReader reader = new
				BufferedReader(new InputStreamReader(url.openStream()));
   		String line = reader.readLine();
   		SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
   		Date date = format.parse(line);
   	}
   	catch(Exception exception) {
   		// Sou um programador inexperiente ou preguiçoso.
   	}
   }
}

O maior problema com o código do Exemplo 2 é que ele poderia apresentar efeitos colaterias indesejados. Qualquer código no bloco try pode lançar uma exceção que seria engolida com uma cláusula catch (Exception). Se uma exceção que não é um ParseException ou IOException for lançada (por exemplo, um SecurityException), o código vai pegá-lo, mas o usuário pode não ficar ciente do que realmente aconteceu. Absorver uma exceção como esta, faz com que o código fique difícil de debugar.

A fim de facilitar o trabalho do programador, Java SE 7 agora inclui uma declaração multi-catch. Isto permite que o programador combine uma clausula catch em um simples bloco de código sem a necessidade de usar uma perigosa cláusula catch-all ou copiar o mesmo código entre vários blocos.

Exemplo 3:

public class ExampleExceptionHandlingNew
{
   public static void main( String[] args )
   {
   	try {
   		URL url = new URL("http://www.yoursimpledate.server/");
   		BufferedReader reader = new BufferedReader(
   			new InputStreamReader(url.openStream()));
   		String line = reader.readLine();
   		SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
   		Date date = format.parse(line);
   	}
   	catch(ParseException | IOException exception) {
   		// Trate seus problemas aqui.
   	}
   }
}

O exemplo 3 mostra como combinar adequadamente as duas declarações em um bloco catch. Observe a sintaxe para a cláusula catch (ParseException | IOException). Esta cláusula catch vai pegar tanto ParseException e IOException.

Então, se você quer agora compartilhar o mesmo código de captura de exceção para duas distintas exceções, você pode usar a sintaxe “Pipe”: (ExceptionType | … | ExceptionType variavle).

Relançar Exceptions

Ao fazer o tratamento de exceções, há momentos em que você quer re-lançar uma exceção que esteja tratando. Um programador inexperiente pode pensar em fazer o seguinte código:

Exemplo 4:

public class ExampleExceptionRethrowInvalid
{
   public static void demoRethrow()throws IOException {
   	try {
 		// Forçando uma IOException aqui como um exemplo,
   		// normalmente algum código começa aqui.
		throw new IOException(“Error”);
   	}
   	catch(Exception exception) {
  		/*
   		 * faça alguma tratativa e então relance a exception.
   		 */
   		throw exception;
   	}
   }

   public static void main( String[] args )
   {
   	try {
   		demoRethrow();
  		}
   	catch(IOException exception) {
   	System.err.println(exception.getMessage());
   	}
   }
}

Mas o compilador não irá compilar o código no Exemplo 4. Exemplo 5 mostra uma maneira de lidar com a exceção e, em seguida, “relançar” ele:

Exemplo 5:

public class ExampleExceptionRethrowOld
{
   public static demoRethrow() {
   	try {
   		throw new IOException("Error");
   	}
   	catch(IOException exception) {
   		/*
   	 	 * Do some handling and then rethrow.
   	 	 */
   		throw new RuntimeException(exception);
   	}
   }

   public static void main( String[] args )
   {
   	try {
   		demoRethrow();
   	}
   	catch(RuntimeException exception) {
   	System.err.println(exception.getCause().getMessage());
   	}
   }
}

O problema com o Exemplo 5 é que não está realmente relançando a excepção original. O código está envolvendo a exceção com uma outra exceção, o que significa que o código seguinte precisa estar ciente de que a exceção foi envolvida. Assim, para tornar possível a captura efetiva da exceção original, uma mudança foi necessária em Java SE (mostrado no exemplo 6).

Exemplo 6:

public class ExampleExceptionRethrowSE7
{
   public static demoRethrow() throws IOException {
   	try {
   		throw new IOException("Error");
   	}
   	catch(Exception exception) {
   		/*
   		 * Do some handling and then rethrow.
   		 */
   		throw exception;
   	}
   }

   public static void main( String[] args )
   {
   	try {
   		demoRethrow();
   	}
   	catch(IOException exception) {
   	System.err.println(exception.getMessage());
   	}
   }
}

Try-Com-Recursos

Você deve ter notado que há um problema com o Exemplo 1 (que é por isso que você nunca deve usar o código do exemplo, em um ambiente de produção sem saber o que ele faz). O problema é que não existe nenhuma limpeza dos recursos utilizados no interior do bloco de teste. Exemplo 7 é uma versão atualizada que descreve como, antes do Java SE 7, um programador resolve este problema.

Exemplo 7:

public class ExampleTryResources
{
   public static void main(String[] args)
   {
   	BufferedReader reader = null;

   	try {
   		URL url = new URL("http://www.yoursimpledate.server/");
   		reader = new BufferedReader(new
				InputStreamReader(url.openStream()));
   		String line = reader.readLine();
   		SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
   		Date date = format.parse(line);
   	}
   	catch (MalformedURLException exception) {
   		// Capturando problemas de conversão de URL.
   	} catch (IOException exception) {
   		// Capturando problemas de I/O.
   	} catch (ParseException exception) {
   		// Capturando problemas de conversão de datas.
   	} finally {
   		if (reader != null) {
   			try {
   				reader.close();
  				 } catch (IOException ex) {
   				ex.printStackTrace();
   			}
   		}
   	}
   }
}

Observe que tivemos que adicionar um bloco finally que fecha o BufferedReader caso ele tenha sido inicializado. Além disso, note que agora temos a variável leitora fora do bloco try. Isso é um pouco mais de código do que necessitamos se a única coisa que você precisa fazer é fechar o leitor se uma exceção I/O acontecer.

No Java SE 7, isto pode ser feito de uma forma mais concisa e limpa, com omostrado no exemplo 8. A nova sintaxe permite que você declare recursos que fazem parte do bloco try. O que isto significa é que você define os recursos antes do tempo e o tempo de execução fecha automaticamente os recursos (caso já não estejam fechados), após a execução do bloco try.

Exemplo 8:

public static void main (String [] args)
 {
    tentar (BufferedReader reader = new BufferedReader (
   	 new InputStreamReader (
   	 nova URL ("http://www.yoursimpledate.server/"). OpenStream ())))
    {
   	 Seqüência de linha = reader.readLine ();
   	 SimpleDateFormat formato = new SimpleDateFormat ("MM / DD / AA");
   	 Data = Data format.parse (linha);
    } Catch (ParseException | exceção IOException) {
   	 // Lidar com os problemas de I / O.
    }
 }

Note que no exemplo 8, a abertura atual acontece na declaração do try (…). Esteja ciente de que este recurso só funciona em classes que implementam a interface AutoCloseable.

Conclusão

A mudanças na manipulação de exceções do Java SE 7 permite que você não apenas programe de forma mais concisa, como demonstrado nos exemplos de multi-catch, mas eles também permitem que você manipule parcialmente uma exceção e, em seguida, relance, como mostrado nos exemplos. Java SE 7 vai também facilitar a criação de códigos para tratativas de erros mais limpos, assim como vimos nos exemplos de try-com-recursos. Estes recursos, juntamente com outros oferecidos pelo Project Coin, permitem que os desenvolvedores Java sejam mais produtivos e escrevam códigos mais eficientes.

Publicidade

Nunca é muito tarde (nem cedo) para aprender a programar

Traduzido de ALT1040
Texto de Pepe Flores

Não seu programador. Ainda que me pareça fascinante o mundo da informática, quando tentei aprender uma linguagem de programação por conta própria, terminei abandonando por uma quantidade inumerável de pretextos. Que não tenho tempo, que é complicado, que tem muita informação para processar. Desculpas. Programar é algo que qualquer pessoa pode fazer (mas não qualquer tem a disposição de aprender). Requer criatividade, inteligência, curiosidade e esforço. Necessita paixão, imaginação, planejamento e improvisação. Mas, mais que nada, se deve ter vontade, como em toda atividade humana.

Faz um ano iniciei uma start-up com uns amigos. Me cerquei de uma equipe excepcional de programadores. Durante os meses de desenho do software, aprendi centenas de lições valiosas, impossíveis de resumir em algumas poucas linhas. Mas, antes de tudo, descobri que o trabalho do programador não perde nada em criatividade de um artista ou a disciplina de um matemático. É a pura faísca de criação, o converter de uma ideia em algo plausível, executável, real. Como diria outro amigo, se convertem litros de café em linhas de código, e as linhas de código em um programa novo, vivo.

Durante esta etapa, entendi como pensar (um pouco) como desenvolvedor. Se aprende a olhar as coisas desde outra perspectiva, desde como fazer possível algo com os recursos que se conta. A observar as possibilidades, a convertê-las em uma série de passos para executar algo, encontrar soluções. Quem tenha criado um software sabe das noites sem dormir e das listas de requerimentos quilométricas. Se aprende a pensar um passo adiante, porque o usuário final, em sua inteligência desajeitada, é capaz de encontrar uma imperfeição, um erro, um conflito em um sistema que consideramos a prova de tolos. Tem que prevenir antes de lamentar.

Não aprendi a programar em nenhuma linguagem, mas sim o mínimo de algumas. E, sobre tudo, a lógica que existe por trás. Isso é importante, porque como diria Arthur C. Clarke, “qualquer tecnologia suficientemente avançada é indistinguível da magia”. Para muitos, o que faz o computador, o telefone ou qualquer dispositivo nos pode parecer questão de feitiçaria. Não é. É resultado de esforço e a mente de milhares de pessoas. Entender os conceitos por trás desta aparente magia nos ajuda a ser mais críticos, mais analíticos, mais compreensivos. Inclusive, mais curiosos e arriscados. Assim como a ciência nos ajuda a entender a natureza, a informática nos explica este mundo virtual que nos rodeia.

Faz um par de dias, li que ensinar a programar aos filhos será equivalente a ensinar a andar de bicicleta. Concordo. Programar vai mais pra lá de escrever linhas e linhas: é uma forma de entender o mundo como criador. Por isso penso que este pensamento crítico deve ser ensinado desde o berço, mas também, que é uma habilidade indispensável para qualquer pessoa. Não necessitamos ser o seguinte Stallman, Torvalds ou Gates. Basta com que, por simples curiosidade, necessidade ou atrevimento, nos animemos a descifrar estas frases aparentemente ininteligível que lhe dão forma a nossa realidade virtual. Nunca é muito tarde (nem muito cedo) para começar.

Hackathons, uma experiência imperdível de conhecimento

Traduzido de ALT1040.

Vá a festas de gente que nãoo conhece” – Alvert-Lásló Barabási, autor do Linked

Um hackathon é um evento organizado por hackers, para hackers, como fim de programar ou construir uma solução de forma colaborativa, durante um prazo determinado de horas, de preferência no mesmo espaço físico. Evidentemente, hackathon é uma palavra composta de hack y marathon, uma corrida em busca do melhor hack possível, uma herança maravilhosa da cultura hacker.Os hackthons ajudam a construir e fortalecer comunidades, obedecem a um modelo de colaboração e competência com tão bons resultados que merece ser imitado em outros âmbitos: na aula, no trabalho, no governo. Além disso, assistir a um hackathon é uma experiência imperdível na vida. Vejamos porque.

Colaboração

O trabalho em equipe é fundamental para participar em um hackathon, um grupo pequeno onde a comunicação flui sem obstáculos, onde as habilidades se somam e o objetivo principal vai além de qualquer ego (no caso ideal). Participar em um hackathon implica colaborar  em uma equipe de respostas rápida, efetivo e criativo para resolver problemas. Visto a uma escala maior, um hackathon é sobre equipes formando uma equipe imensa, total, para materializar as melhores idéias.

Redes

Vistos com maior profundidade, os hackathons são eventos de redes. Onde os assistentes (e cada uma de suas idéias) são nós, e a comunicação entre eles são as conexões: a exaustiva distribuição de idéias. Em um hackathon as pessoas estendem suas redes de contatos, sim, mas mais ainda sua coleção de idéias novas. Em um evento assim as idéias competem e se disseminam exponencialmente: ao final, um equilíbrio particular filtra as melhores, porque todas as idéias são discutidas, detalhadas, misturadas e, eventualmente, evolucionadas. Os hackathons geram redes abertas e adaptáveis de conhecimento.

Conhecimento

Um hackathon é um evento que cataliza a geração e distribuição de conhecimento porque concentra mentes dispostas a colaborar em redes. Redes de pessoas autônomas, autodidatas, participativas. Assim mesmo, se trata de um evento onde as idéias são analisadas, inclusive melhoradas, por e para a comunidade. Os hackathons são as oportunidades de praticar intensamente a aprendizagem baseada em problemas. Se na aula primeiro aprendemos conceitos e logo resolvemos problemas, nos hackathons sucede justamente o contrário. E funciona muito bem.

Como começar

Por sua definição os hackathons são eventos feitos para programadores, como dito acima apresentam um modelo a seguir para todos aqueles que amam aprender solucionando problemas. Por exemplo, tive a oportunidade de utilizá-los em minhas aulas de programação desta forma:

  1. Apresentação de um problema, de preferência real
  2. Formação de equipes de trabalho de quatro a cinco alunos
  3. Definição de ferramentas de trabalho
  4. Debate em equipe e logo de forma grupal os elementos do problema
  5. Definição do formato de entrega de resultados, em tempo e forma
  6. Desenvolvimento de soluções criativas, perturbadoras, efetivas
  7. Apresentação por equipe da aproximação ao problema: a essência da sua solução
  8. Breve roda de perguntas e respostas
  9. Seleção das melhores soluções
  10. Reflexão autocrítica para melhorar.

Esta é uma pequena metodologia que não é em absoluto original, porém funciona para que os alunos colaborem, formem redes de idéias e se potencializa o conhecimento a partir da solução de um problema específico. Imaginemos este modelo sobre tudo em âmbitos fechados como os governamentais ou inclusive empresariais.

Você pode começar por você mesmo de forma autodidata, com seu grupo de amigos, em sia comunidade, preparar seu próprio hackathon ou participar nos que acontecem em seu país, visitar ou inaugurar um hacklab ou hackerspace, deixe-se contaminar de boas idéias, imagine como uma cadeia de DNA necessitada da rica informação genética de outros. O ponto é aprender, desenvolver ao máximo seus talentos, inclusive descobrir-los quando está em seu limite.

Um hackathon, idealmente, é sobre servir a uma causa comum. E funciona.

10 plataformas inovadoras para aprender a programar

Traduzido de ALT1040

Se não aprendemos a programar, nos arriscamos a ser programados… Programe ou seja programado. – Douglas Rushkoff

Acho que para todos aqui está claro que a educação formal, inclusive a universitária, está defasada se não totalmente ultrapassada pela Internet. Com isso me refiro a que a educação formal não aproveita – e as vezes nem sequer re(conhece) – para seu benefício as ferramentas técnicas e metodológicas que a Internet nos está fornecendo. Falo de ferramentas que facilitam e potencializam a aprendizagem em términos colaborativos, massivos, autônomos, inovadores, críticos, ágeis, evolutivos, usáveis e demais.

Não é um assunto fácil o avanço da tecnologia. A educação formal é um gigante que requer uma quantidade enorme de energia para mover um passo. Com os estudantes, sobre tudo entre a geração que nasceu com a Internet, é diferente: hábil para a sobre-informação, as mudanças rápidas e a educação absolutamente informal, de aprendizagem invisível. E justamente por isso é que as instituições universitárias deveriam imitar uma ou mais das seguintes plataformas de aprendizagem, especializadas no ensino da programação mas não menos úteis para outras áreas do conhecimento, só basta imaginá-lo um pouco.

1. Codecademy

Com uma interface limpa e mensagem clara: Aprenda a fazer código. Ponto. Como? A proposta é com JavaScript, a linguagem nativa dos navegadores web, ainda que também conte com outras ferramentas essenciais para fazer web como HTML5 e jQuery. Também é possível criar seus próprios cursos, fazer comunidade, ganhar reputação, inclusive ganhar condecorações sociais por suas conquistas. Codecademy tem um enorme potencial.

2. Try Ruby

Creio que não me equivoco ao dizer que a comunidade em prol da linguagem Ruby tem os tutoriais de aprendizagem de programação mais lindos e divertidos de todos. Por exemplo o famoso Hackety Hack e os espirituais Ruby Koans. Por sua parte, Try Ruby, é um tutorial interativo, quase como um conto programável, que convida a descobrir esta bela linguagem. Eu não pensaria duas vezes e me daria uma oportunidade de aprender Ruby o quanto antes.

3. Skillshare

“Aprenda o que seja de quem seja, onde seja”. Esta é a promessa de uma plataforma que conecta uma rede de nós professor/aluno, pessoas que aprendem e ensinam também a programar através de cursos onde a aprendizagem é guiada por uma comunidade.

4. Programr

Programe agora mesmo Java, PHP, C++, Python e mais linguagens de programação em seu navegador, sobre três princípios básicos: aprenda, codifique e comparta. A interface não é a mais bela, porém em termos estruturais funciona bem. Seus desafios de programação são uma excelente ideia.

5. Team Tree House

Sobre o lema “O que quer aprender hoje?”, Team Tree House oferece cursos on-line, baseados em vídeos curtos, muito bem explicados e sequenciados, sobre programação web e programação de dispositivos móveis com iOS. É necessário pagar uma assinatura para ter acesso a todos os materiais, que com certeza se atualizam e crescem com frequência. Me encanta que utilizem condecorações e que estas sejam um indício de uma educação que vai mais longe do que títulos universitários.

6. Code School

“Aprenda fazendo” é uma plataforma apoiada por IBM, Github, AT&T, cheia de cursos on-line, também orientada para a gameficação da educação. O desenho da página é fabuloso. Merece um artigo a parte para discutir sobre o futuro da educação da programação.

7. Khan Academy

Esta plataforma é o YouTube da educação on-line, repleta de vídeos de aulas completas de programação e muitos outros temas. Apesar de que em comparação com as outras plataformas Khan Academy parece tradicional, o mais importante é que funciona (inclusive em móveis).

8. Hackasaurus

Mozilla sempre está preocupada pela educação em torno da web aberta, baseada em padrões, com o navegador como laboratório de idéias cozinhadas com HTML5. Hackasaurus é uma atrativa tentativa de levar esta aprendizagem a outro nível, quase como os blocos de Lego, onde a programação é construir, misturar, experimentar: um ato absolutamente criativo.

9. Stanford University

Aqui não tem mais do que vídeos e apresentações tradicionais. Porém no fundo temos um esforço acadêmico imenso dos professores da Universidade de Stanford em oferecer de maneira coerente o que alguns vêm como o melhor curso de programação de aplicações móveis para iOS na rede. Seria incrível uma versão massiva como o curso de inteligência artificial que Norvig y Thrun deram no final do ano anterior.

10. P2P University

Todos professores, todos alunos: educação P2P, entre iguais. Educação colaborativa, construída por comunidades de entusiastas, com espírito de código aberto e cultura livre. Como conceito é maravilhoso; como implementação segue em constante evolução, muito orgânica. Aqui encontrará excelentes cursos de programação, alguns de temas raros, mas todos interessantes.

Centralizar uma janela PopUp na aplicação Adobe Flex

Centralizar uma Janela com Popup em Flex

 

 

 

 

 

 

 

 

 

 

 

Um recurso muito utilizado nas aplicações Flex são as janelas do estilo PopUp, que são aquelas que abrem sobre sua aplicação, podendo inclusive serem movidas pelo usuário. Normalmente quando abrimos uma nova janela desse tipo queremos que a mesma apareça exatamente no centro da tela, ou seja, da aplicação.

Para isso utilizamos o seguinte código:

PopUpManager.addPopUp(myPopUp, this, true);
PopUpManager.centerPopUp(myPopUp);

Normalmente utilizamos estes três parâmetros:

window: Nossa janela que desejamos exibir
parent: Componente pai que será utilizado como referência para posicionar a nova janela
modal: Variável booleana que define se nossa janela será do tipo Modal (se irá inibir o restante da aplicação).

O método centerPopUp, como o próprio nome diz, é utilizado para centralizar a janela sobre o componente pai. Aqui começa nosso problema. Quando o “parent” é nosso Application, tudo fica perfeito, pois nossa janela ficará exatamente no centro da aplicação do usuário. Entretanto se estamos executando nosso código, a partir de um sub-componente, por exemplo um que esteja na parte de baixo da aplicação, nossa janela popup será centralizada sobre sobre este componente.

Para corrigir isso, utilizamos o seguinte código:

PopUpManager.addPopUp(concessionaria,
                      DisplayObject(this.parentApplication),true);
PopUpManager.centerPopUp(concessionaria);

Desta forma estaremos dizendo ao PopUpManager que o componente pai da nossa aplicação será nosso Application, fazendo com que nossas janelas PopUp sempre sejam centralizadas sobre nossa aplicação.

Que tal, ótima dica não? Abs!