Java 9 na prática: REPL

Java 9 na prática: REPL
rodrigo.turini
rodrigo.turini

Compartilhe

Estamos acompanhado de perto as novidades do Java 9 e desde já testando cada uma das muitas propostas (JEPs) que já foram aceitas e integradas em seus builds mais recentes. O release final deverá acontecer apenas em março de 2017, mas a fase em que todas as features deverão estar completas está próxima: faltam apenas dois meses!

Este será o primeiro post de uma série que te possibilitará acompanhar toda a evolução da nova versão da linguagem até o seu tão esperado lançamento oficial. A decisão de qual recurso mostrar nesse primeiro post não foi fácil, são muitas novidades interessantes, mas convenientemente uma delas nos ajudará a testar grande parte das demais: o REPL.

Read-Eval-Print-Loop (REPL)

Se você já programa em linguagens como Scala, Ruby, Swift e JavaScript entre tantas outras, possivelmente já brincou com algum tipo de REPL. Essa ferramenta nada mais é do que um ambiente simples e interativo onde você pode facilmente executar códigos, oferecendo uma forma bastante efetiva de experimentar novos recursos e APIs.

Vale a pena ler esse trecho presente na motivação do proposta:

Exploration of coding options is also important for developers prototyping code or investigating a new API. Interactive evaluation is vastly more efficient in this regard than edit/compile/execute and System.out.println. Without the ceremony of class Foo { public static void main(String[] args) { ... } }, learning and exploration is streamlined.

Instalando o último build do JDK 9

Antes de mais nada você precisará instalar um build recente do JDK 9 para testar o conteúdo desse e dos futuros posts. O processo não é trabalhoso, eu recomendo bastante que você não fique apenas na teoria. Além disso, novas versões estão sempre disponíveis, não deixe de atualizar sempre que for experimentar um novo recurso.

Você encontra o ultimo build do JDK 9 aqui e, após fazer download, basta apontar seu JAVA_HOME para essa instalação e usar o comando java -version pra confirmar que o processo deu certo.

Download e execução do REPL

Feito isso, você já poderá baixar a implementação de REPL do Java 9, que é conhecida como Kulla (aka JShell). Há sempre a opção de clonar o repositório Mercurial do projeto, compilar e buildar manualmente, mas você não precisa fazer nada disso. Para testar, basta baixar o JAR disponível nessa instância do Cloudbees do AdoptOpenJDK.

Tudo pronto, java -jar nele e você já estará usando o REPL. O build usado nesse post foi o kulla--20160126010041.jar, caso você queira usar a mesma versão.

 Turini $ java -jar kulla--20160126010041.jar

| Welcome to JShell -- Version 9-ea | Type /help for help 

Uma nova forma de experimentar código em Java

Chegou a hora de colocar as mãos na massa, mas aqui vai um aviso: isso é viciante. Eu não passo um dia sem usar o REPL desde que instalei ele aqui pela primeira vez, e estou falando de experimentar código do dia a dia, não só dos novos recursos da linguagem.

Podemos começar criando uma nova variável chamada valor, que guardará um inteiro:

 int valor = 100; | Added variable valor of type int with initial value 100 

Repare que há um feedback para todas as suas ações. Você pode desativá-lo com o comando /feedback off, mas eu pessoalmente gosto. Digite /feedback e pressione o tab pra ver as demais opções. Não deixe de usar o tab (autocomplete) sempre que for usar um comando novo pra ver todas as suas possibilidades.

Com ou sem ponto e vírgula?

Ah, sabe o ponto e vírgula clássico do final da linha? No REPL é opcional:

 int valor = 100 | Modified variable valor of type int with initial value 100 

É um tanto conveniente, mas eu sinceramente ainda não me acostumei.

Trabalhando com variáveis temporárias

E tem mais! Você também não precisa declarar o tipo das variáveis:

 semTipo = 100 | Error: | cannot find symbol | symbol: variable semTipo | semTipo = 100 | ^-----^ 

Ops, precisa sim! Esse foi só um exemplo pra você ver a saída de um comando inválido. Por outro lado, se você não declarar o nome da variável, o comando será aceito. Experimente digitar apenas o número 100, ou ainda fazer alguma operação matemática sem declarar o tipo e variável de retorno:

 valor / 3 | Expression value is: 33 | assigned to temporary variable $3 of type int 

O resultado da expressão foi salvo em uma variável temporária, nesse caso chamada $3. Veja que o feedback nos avisou o nome da variável e também o seu tipo. Se quiser testar, você pode fazer um sysout na nova variável:

 System.out.println($3) 33 

Legal, não é? Você também pode usar o comando /vars pra visualizar todas as variáveis disponíveis, incluindo as temporárias:

 /vars | int valor = 100 | int $3 = 33 | double pi = 3.141592653589793 

Apagando e editando variáveis

Quer apagar alguma delas? Use o /drop com o ID ou nome da variável:

 /drop pi 

Ou se preferir, você também pode editá-la com o comando /edit.

Screen Shot 2016-03-29 at 00.35.22

Ouch, que editor é esse? Se você é dos meus, vai preferir fazer isso no melhor editor do mundo: o VIM. O comando /seteditor te ajudará com isso:

 /seteditor vim | Editor set to: vim 

Explorando as APIs do Java

Lembre que você está em um ambiente Java, você pode usar qualquer classe da API. Ah, e você pode sempre usar o TAB como atalho para autocompletar. Na classe Math, por exemplo:

Screen Shot 2016-03-29 at 01.02.16

Experimente chamar algum de seus métodos:

 Math.random() | Expression value is: 0.12308153862256899 | assigned to temporary variable $6 of type double 

Declarando métodos e classes

O JSheel vai bem além das variáveis e evaluações simples, você também pode criar métodos ou mesmo classes. Lembra do clássico desafio da sequência de fibonacci? Que tal resolvê-lo assim:

 long fibonacci(int n) { if(n<2) return n; return fibonacci(n-1) + fibonacci(n-2); } | Added method fibonacci(int) 

Vamos ver se eu acertei na lógica? Posso fazer um for de 0 a 4 imprimindo a saída:

 for(int i=0; i<5; i++) System.out.println(fibonacci(i)) 0 1 1 2 3 

Também poderíamos ter criado uma classe Fibonacci com esse método dentro, mas criei fora de uma classe justamente pra demonstrar que isso é aceito. Você pode usar os comandos /methods e /classes para listar todos os métodos e classes disponíveis. O /drop e /edit também funcionam pra deletar e editar as classes e métodos.

E quanto aos imports?

E se no lugar do for clássico eu quisesse usar a API de Streams do Java 8 para iterar e imprimir a sequência de Fibonacci? Não tem erro, basta digitar Stream e ops...

 Stream.of(1,2,3,4) | Error: | cannot find symbol | symbol: variable Stream | Stream.of(1,2,3,4) | ^----^ 

Eu preciso importar essa API! Até agora não tinhamos precisado importar nada, já que só usamos classes e métodos disponíveis nos imports default. Você pode usar o comando /imports pra ver o que já está disponível. Para usar a API de Streams, basta importá-la:

 import java.util.stream.\* 

Perfeito, já podemos usar suas classes a vontade:

 Stream.of(1,2,3,4).map(i -> fibonacci(i)).forEach(System.out::println) 1 1 2 3 

Experimente também usar o /help para ver uma lista com todos os comandos disponíveis.

Acompanhando as novidades do Java 9

Vamos sempre postar novidades da nova versão da linguagem aqui e no blog do Alura. A lista de discussão do Java 9 está bastante movimentada, não deixe de passear por lá. Se você ainda não conhece Java 8, vai gostar de ver esse curso do Alura e também nosso curso de Arquitetura da Caelum.

E você, o que achou do REPL? Tenho a impressão que será bastante usado em nosso dia a dia e também nas salas de aula. O que você acha?

Veja outros artigos sobre Programação