Java 9 na prática: REPL

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?

Tags:

32 Comentários

  1. Marcelo Eugenio 06/04/2016 at 12:57 #

    Parabéns pelo artigo, Turini! que venha os próximos sobre Java 9.

  2. Rodrigo Turini 06/04/2016 at 13:00 #

    Obrigado, Marcelo! Já estou trabalhando no próximo. Tem bastante novidade

  3. Douglas Arantes 06/04/2016 at 13:13 #

    Parabéns pelo post.

    Acredito que se inferência de variáveis locais com var e val forem incluídos no Java 9, o adoção do REPL vai ser maior.

  4. Rodrigo Turini 06/04/2016 at 13:26 #

    Oi Douglas, muito obrigado!

    Bem observado. A JEP286 http://openjdk.java.net/jeps/286 ainda está em status candidate.

    Tem uma pesquisa rolando pra pegar a opinião da comunidade, está na segunda fase:
    http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000062.html

    E ai, será que entra mesmo?

  5. Fanime 06/04/2016 at 14:45 #

    Poxa, mto bacana. Ansioso aqui.
    E concordo com o Douglas, a adição de inferência por var/val será mto bacana.

    O que me preocupa é o Java EE 8. Tenho visto mtos comentários da comunidade dizendo que a Oracle teria perdido o interesse, e que mtas das especificações estariam paradas/atrasadas.
    Inclusive, um ex-evangelista saiu da Oracle, e montou o “Java EE Guardians”.

    Turini, considerando que vc faz parte da equipe que desenvolve o Ozark (MVC 1.0), o que pensa sobre isso?

  6. Rodrigo Turini 06/04/2016 at 15:12 #

    Oi Fanime;

    Isso é verdade sim, e algumas specs estão com timing atrasado.
    Mas o Java EE vai bem além da Oracle, o Java EE guardians é uma prova disso.

    As listas de lá estão bastante movimentadas, tenho participado também.
    Além disso, agora é um bom momento pra comunidade estar ainda mais presente.
    Planejo escrever um post em breve sobre isso, e sobre o MVC + JAX-RS.

  7. Leonardo 11/04/2016 at 08:28 #

    Parabéns cara, muito bom o artigo, estou ansioso para os próximos, abraço.

  8. Vanderson Assis 11/04/2016 at 09:01 #

    Java não para de surpreender, bacana pacas…

  9. Felipe 11/04/2016 at 15:06 #

    Tuirini, primeiramente ótimo artigo, parabéns.

    Você sabe se a API Money vira na versão 9?

  10. jairo 11/04/2016 at 15:29 #

    Interessante demais! Imagine um “rails c” nas nossas aplicações java 🙂

    Sugestão: Seria legal um artigo sobre modularização e como isso vai se encaixar no sistema de pacotes e artefatos da plataforma. Como isso vai interferir com os pipelines de build e gerência de dependências atuais.

  11. Rodrigo Turini 11/04/2016 at 15:54 #

    Oi Leonardo, em breve sai um lá no blog do Alura 🙂

  12. Rodrigo Turini 11/04/2016 at 15:55 #

    sem dúvidas, Vanderson. A linguagem está indo pra um caminho bem legal.

  13. Rodrigo Turini 11/04/2016 at 15:58 #

    Oi Felipe,

    ainda não, empurraram essa um pouco mais pra frente.

    Dá pra ver a lista das propostas aqui:

    http://openjdk.java.net/projects/jdk9/

  14. Rodrigo Turini 11/04/2016 at 15:59 #

    Jairo, muito boa a sugestão! Já está na minha TODO list de posts, chega em breve 🙂

  15. Christoffer Lucas 11/04/2016 at 20:41 #

    Parabéns pelo artigo. essa funcionalidade REPL no Java é top. Não que um dia fariam isso. Acabou a idéa implementar metodos, e usar sysout para testar. Top

  16. Ricardo Johannsen 12/04/2016 at 19:29 #

    Olá Turini, esse Java EE guardians seria um “outro” Spring Framework?

  17. FelipeVR 12/04/2016 at 19:59 #

    O artigo parece bastante interessante, porém não pude ler praticamente nada dele e portanto faço uma sugestão:

    Seria legal se usassem algum tipo de forma pra entrada de código, bem comim em quase todos os sites/blogs que trabalham com tutoriais assim que creio que até a caellum use em outros posts.

    No entanto, aqui, tudo que envolva códigos foi colocado como imagens e nós, cegos, não podemos ver nada disso.

    Seria legal se os comandos, bem como as saídas fossem apresentados textualmente, garantindo um melhor acesso a este que parece ser um post muito bom e útil.

    Obrigado!

  18. Rodrigo Turini 12/04/2016 at 22:17 #

    Oi Ricardo.

    O Java EE Guardians é na verdade um grupo de usuários que uniu forças pra manter o Java EE.

    Uma descrição bastante encontrada:

    “Rahman and members of the community he served have joined forces to form the Java EE Guardians, a group of volunteers committed to supporting enterprise Java where they believe Oracle is falling down on the job.

  19. Rodrigo Turini 12/04/2016 at 22:25 #

    Oi Felipe, tem toda razão.

    Vou pesquisar melhores formas de melhorar a acessibilidade do post e atualizá-lo em breve.
    Escolhi imagens pra conseguir mostrar o JShell, mas não pensei por esse lado.

    Gostei bastante da sugestão, muito obrigado.

  20. Magno Costa 15/04/2016 at 09:02 #

    Olá Rodrigo,

    Muito maneiro essa nova ferramenta pra a plataforma Java. No post vc comentou sobre o Vim vc usa ele pra coda em Java?

  21. Rodrigo Turini 15/04/2016 at 09:41 #

    Oi Magno. Pra codar Java eu uso Intellij, mas ele tem suporte aos atalhos do vim 🙂

  22. Rodrigo 17/04/2016 at 01:12 #

    Otimo artigo Rodrigo Turini(meu chará), Estou estudando sobre as tendencia do java 9 , e resolve cria um artigo sobre o Jshel, muito legal.
    Meu Artigo em meu blog, Confiram:
    https://digaotutoriais.wordpress.com/2016/04/17/java-9-introducao-ao-jshell-projeto-kulla/

  23. Rodrigo Turini 17/04/2016 at 01:26 #

    Oi Felipe, só pra avisar, migrei as imagens para snippets de código.
    Isso já deve melhorar a acessibilidade do post.
    Qualquer coisa nos avise, e mais uma vez obrigado por nos avisar. Um abraço

    Oi Rodrigo. Muito obrigado e parabéns pelo seu post, acabei de ler.

  24. Raphael Lacerda 13/06/2016 at 15:02 #

    Post legal demais!

  25. Alexsandro Lopes 26/09/2016 at 14:04 #

    Soube que haverá uma modularização na linguagem, com isso os métodos deprecated serão retirados da API?

  26. Rodrigo Turini 26/09/2016 at 15:42 #

    Oi Alexsandro!

    Já existe e está integrado ao Java 9 sim, escrevi inclusive um post de introdução ao JigSaw, que é o nome do projeto que traz essa modularidade para linguagem:

    http://blog.caelum.com.br/java-9-na-pratica-jigsaw/

  27. Helcio da Silva 02/01/2017 at 22:50 #

    Ótimo post Turinu.
    Você saberia me dizer se já é possível adicionar uma biblioteca no classpath?
    É que eu gostaria de testar alguns frameworks direto no JShell.

  28. Rodrigo Turini 02/01/2017 at 23:16 #

    Oi Helcio

    muito obrigado! e sobre adicionar JAR externos, tem sim, com o comando /cp (ou /classpath).

    a grande proposta desse recurso é exatamente que você consega experimentar as classes de fora do JRE

    basta passar o /cp .

Deixe uma resposta