JavaRush /Blogue Java /Random-PT /Java 11 lançado: novos recursos e capacidades

Java 11 lançado: novos recursos e capacidades

Publicado no grupo Random-PT
Anteriormente, novas versões do Java apareciam raramente e com atrasos. Agora a Oracle mantém com sucesso seu ritmo autodefinido de “novo Java a cada seis meses”. Então, há poucos dias, dentro do prazo, finalmente recebemos o Java SE 11 e a implementação do JDK (Java Development Kit). Java 11 lançado: novos recursos e capacidades - 1Como sempre, a nova versão será compatível com as antigas e o suporte para Java 11 não terminará antes de dezembro de 2026.

Novos recursos no Java SE 11 (visíveis para desenvolvedores)

Lembre-se que em Java as mudanças são feitas por meio da implementação do JEP “JDK Enhancement Proposal”. JEP é uma proposta para melhorar o OpenJDK e pode ser aprovada, adiada ou rejeitada. Isto é, em essência, uma coleção de JEPs é uma estratégia de desenvolvimento para OpenJDK. Entre colchetes antes do novo “recurso” indicaremos o número do PEC correspondente. [323] Sintaxe de variável local para parâmetros Lambda - sintaxe var para parâmetros lambda O Java 10 introduziu a palavra-chave var, que tornou possível não especificar explicitamente o tipo de uma variável local. Isso simplificou o código. JEP 323 expande o uso desta sintaxe com expressões lambda. Exemplo simples:
list.stream ()
                 .map ((var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
Como escreve Simon Ritter , um conhecido evangelista Java, um programador Java experiente notará que usar var neste caso pode ser desnecessário, pois o código acima pode ser substituído pelo seguinte:
list.stream ()
                  .map (s -> s.toLowerCase ())
                  .collect (Collectors.toList ());
Por que, então, apoiar var? Há apenas um caso especial – quando você deseja adicionar uma anotação a um parâmetro lambda. Isso não pode ser feito sem algum tipo envolvido, e para evitar ter que usar um tipo explícito, podemos simplificar tudo usando var assim:
list.stream ()
                 .map ((@ Notnull var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
[330] Lançar programas de código-fonte de arquivo único Aprimorando o iniciador Java para lançar um programa como um arquivo único com código-fonte Java Java é frequentemente criticado por sua sintaxe detalhada e “cerimônia” de várias etapas de lançamento até mesmo de um aplicativo trivial. Às vezes isso assusta os novatos. Para escrever um aplicativo que simplesmente imprima " Hello World! " ", você precisa escrever uma classe com um voidmétodo main estático público e usar o System.out.println. Feito isso, você deve compilar o código usando javac . Finalmente, depois disso, você pode iniciar o aplicativo, que exibirá a malfadada saudação (é claro, o ambiente de desenvolvimento integrado, tanto o IDEA quanto o integrado ao JavaRush , executa essa “mágica de inicialização do aplicativo” por conta própria - nota do editor ). Sejamos honestos: na maioria das linguagens de programação, o script real para executar programas parece muito mais simples. O JEP 330 elimina a necessidade de compilar um aplicativo de arquivo único, então agora se você usar a linha de comando, basta digitar
java HelloWorld.java
O iniciador Java detectará que o arquivo contém código-fonte Java e compilará o código em um arquivo de classe antes de executá-lo. Você pode colocar parâmetros antes ou depois do nome do arquivo de código-fonte. Aqueles colocados após o nome são passados ​​como parâmetros quando a aplicação é executada. Aqueles colocados antes do nome são passados ​​​​como parâmetros para o inicializador Java após a compilação do código. Opções específicas do compilador (como classpath) também serão passadas ao javac para compilação. Exemplo. Linha:
java -classpath / home / foo / java Hello.java Bonjour
será equivalente a estas linhas:
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] Cliente HTTP (padrão) - O suporte à API do cliente HTTP foi padronizado. O JDK 9 introduziu uma nova API para suportar o protocolo do cliente HTTP (JEP 110) . Como o JDK 9 também introduziu o Java Platform Module System (JPMS) , esta API foi incluída como um módulo incubador (são módulos para fornecer aos desenvolvedores novas APIs que ainda não se tornaram padrão no Java SE, enquanto as APIs "vivas" estão sendo preparado para remoção - os desenvolvedores podem experimentar novas APIs e tentar fornecer feedback). Depois que as alterações necessárias forem feitas (esta API foi atualizada no JDK 10), a API poderá se tornar parte do padrão. Portanto, a API do cliente HTTP agora está oficialmente incluída no Java SE 11 . Isto introduz um novo módulo e pacote para o JDK, java.net.http . Os principais novos tipos são: HttpClient HttpRequest HttpResponse WebSocket Esta API pode ser usada de forma síncrona ou assíncrona. No modo assíncrono, CompletionFuturese são usados CompletionStages​​. [320] Remover os módulos Java EE e CORBA Com a introdução do Java Platform Module System (JPMS) na nona versão do Java, tornou-se possível dividir o arquivo rt.jar monolítico em vários módulos. Além disso, o JPMS permite criar um ambiente de execução Java que inclui apenas os módulos necessários à sua aplicação, reduzindo bastante seu tamanho. Com limites de módulo definidos de forma transparente, é muito mais fácil remover partes obsoletas da API Java - é isso que faz o JEP 320. O metamódulo java.se.ee inclui seis módulos que não farão parte do padrão Java SE 11 e não serão incluídos no JDK:
  • corba
  • transação
  • ativação
  • xml.bind
  • xml.ws
  • xml.ws.annotation
Esses módulos foram descontinuados no JDK 9 e não foram incluídos por padrão na compilação ou execução. Isso significa que se você tentou compilar ou executar um aplicativo que usa APIs desses módulos no JDK 9 ou JDK 10, ele falhou. Se você usar as APIs desses módulos em seu código, precisará fornecê-los como um módulo ou biblioteca separada.

Novas APIs

Um grande número de novas APIs no JDK 11 apareceram graças à inclusão dos módulos HTTP Client e Flight Recorder no padrão de linguagem . Para obter uma lista completa de APIs, consulte a seguinte comparação abrangente de diferentes versões do JDK , compilada por Gunnar Morling. E nesta nota listaremos alguns novos métodos que não estão incluídos nos módulos java.net.http , jdk.jfr e java.security . java.lang.String Indiscutivelmente uma das mudanças mais importantes em String na API JDK 11, existem vários novos métodos úteis.
  • boolean isBlank (): retorna verdadeiro se a string estiver vazia ou contiver apenas espaços; caso contrário, falso.

  • Stream lines(): Retorna um fluxo de linhas extraídas desta string, separadas por terminadores de linha.

  • String repeat (int): Retorna uma string cujo valor é a concatenação dessa string repetida int vezes.

  • String strip (): Retorna uma string com todos os espaços removidos antes ou depois do primeiro caractere que não seja espaço.

  • String stripLeading (): Retorna uma string com todos os espaços até o primeiro caractere sem espaço removido.

  • String stripTrainling (): Retorna uma string com todos os espaços que ocorrem após a remoção do último caractere sem espaço.
strip()O método já fez algo parecido trim (), mas por espaços esses métodos significam coisas diferentes. No caso, trim()apenas os espaços são cortados, e no caso strip()- também caracteres especiais, como tabulações. java.lang.StringBuffer java.lang.StringBuilder Ambas as classes contêm um novo método compareTo ()que aceita StringBuffer/ StringBuildere retorna int. O método de comparação lexical é semelhante ao novo método compareTo() CharSequence. java.io.ByteArrayOutputStream
  • void writeBytes (byte []): grava todos os bytes do parâmetro no fluxo de saída java.io.FileReader
Existem dois novos construtores aqui que permitem especificar arquivos Charset. java.io.FileWriter Quatro novos construtores que permitem especificar Charset. java.io.InputStream
  • io.InputStream nullInputStream (): retorna InputStream, que não lê nenhum byte. Como usar este método? Você pode pensar nisso como algo como /dev/null para descartar a saída desnecessária ou para injetar uma entrada que sempre retorna zero bytes.
java.io.OutputStream
  • io.OutputStream nullOutputStream ()
java.io.Reader
  • io.Reader nullReader ()
java.io.Writer
  • io.Writer nullWriter ()
java.lang.Character
  • String toString (int): Esta é uma sobrecarga de um método existente, mas usa int em vez de char.
java.lang.CharSequence
  • int compare (CharSequence, CharSequence): compara lexicograficamente duas instâncias CharSequence. Retorna um valor negativo, zero ou um valor positivo se a primeira sequência for lexicograficamente menor, igual ou maior que a segunda, respectivamente.
java.lang.ref.Reference
    lang.Object clone (): O evangelista Java Simon Ritter admite que esse método o confunde. A classe Referencenão implementa uma interface Cloneablee este método sempre lançará uma exceção CloneNotSupportedException. No entanto, o especialista sugere que este método será útil para algo no futuro.
java.lang.Runtime java.lang.System Não há métodos novos aqui. Vamos apenas mencionar que o método runFinalizersOnExit ()foi removido de ambas as classes, o que pode causar problemas de compatibilidade. java.lang.Thread Sem métodos adicionais, apenas mencionaremos que destroy ()eles stop (Throwable)foram removidos. No entanto stop (), que não aceita argumentos, ainda está disponível. Tenha isso em mente, pois pode haver problemas de compatibilidade. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer Em todas essas classes, os desenvolvedores da linguagem adicionaram um método mismatch ()que encontra e retorna o índice relativo do primeira incompatibilidade entre este buffer e um determinado buffer. java.nio.channels.SelectionKey
  • int interestOpsAnd (int)

  • int interestOpsOr (int)
java.nio.channels.Selector
  • int select (java.util.function.Consumer, long): Seleciona e executa uma ação nas teclas cujos canais correspondentes estão prontos para operações de E/S. O parâmetro longo é um tempo limite.

  • int select (java.util.function.Consumer): funciona como o método acima, mas sem tempo limite.

  • int selectNow (java.util.function.Consumer): funciona como o método acima, só que não bloqueia.

java.nio.file.Files
  • String readString (Path): Lê todo o conteúdo de um arquivo em uma string, decodificando bytes em caracteres usando a codificação UTF-8 .

  • String readString (Path, Charset): Funciona como o método acima, mas decodifica bytes em caracteres usando Charset.

  • Path writeString (Path, CharSequence, java.nio.file. OpenOption []): se você gravar uma sequência de caracteres CharSequenceem um arquivo, esses caracteres serão codificados em bytes (usando UTF-8 ).

  • Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption []): funciona como o método acima, apenas os caracteres são codificados em bytes usando Charset.
java.nio.file.Path
  • Path(String, String[]): Retorna o Path, transformando um pathstring ou sequência de strings que quando combinadas formam um pathstring.

  • Caminho (net.URI): Retorna o caminho transformando o URI.
java.util.Collection
  • Object [] toArray (java.util.function.IntFunction): Retorna um array contendo todos os elementos desta coleção, usando a função geradora fornecida para distribuir o array retornado.
java.util.concurrent.PriorityBlockingQueue java.util.PriorityQueue
  • void forEach (java.util.function.Consumer): executa a ação especificada em cada elemento Iterable até que todos os elementos tenham sido processados ​​ou a ação gere uma exceção.

  • boolean removeAll (java.util.Collection): remove todos os elementos desta coleção que também estão contidos na coleção especificada (operação opcional).

  • boolean removeIf (java.util.function.Predicate): remove todos os elementos desta coleção que satisfazem o predicado fornecido.

  • boolean retainAll (java.util.Collection): preserva apenas os elementos desta coleção que estão contidos na coleção especificada (operação opcional).
java.util.concurrent.TimeUnit
  • long convert (java.time.Duration): Converte a duração de tempo fornecida para esta unidade.
java.util.function.Predicate
  • Predicate not(Predicate): retorna um predicado que é a negação do predicado fornecido.
Por exemplo, o seguinte código:
lines.stream ()

.filter (s ->! s.isBlank ())
pode ser convertido para isto:
lines.stream ()

.filter (Predicate.not (String :: ISBLANK))
e se usarmos importação estática, obteremos isso:
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
  • boolean isEmpty (): Retorna verdadeiro se não houver valor , falso caso contrário .
java.util.regex.Pattern
  • Predicate asMatchPredicate (): O especialista em Java Simon Ritter acredita que pode haver uma jóia real da API JDK 11 escondida aqui. Este método cria um predicado que verifica se este padrão corresponde a uma determinada string de entrada.
java.util.zip.Deflater
  • int deflate (ByteBuffer): compacta os dados de entrada e preenche o buffer especificado com dados compactados.

  • int deflate (ByteBuffer, int): compacta os dados de entrada e preenche o buffer especificado com dados compactados. Retorna a quantidade real de dados compactados.

  • void setDictionary (ByteBuffer): define o dicionário fornecido para ser compactado em bytes no buffer fornecido. Esta é uma sobrecarga de um método existente que agora pode aceitar um ByteBuffer, em vez de uma matriz de bytes.

  • void setInput (ByteBuffer): Define os dados de entrada a serem compactados. É também uma sobrecarga de um método existente.
java.util.zip.Inflater
  • int inflate (ByteBuffer): descompacta bytes no buffer especificado. Retorna o número real de bytes não compactados.

  • void setDictionary (ByteBuffer): Define o dicionário fornecido para os bytes no buffer fornecido. É uma forma sobrecarregada de um método existente.

  • void setInput (ByteBuffer): Define os dados de entrada para descompressão. Uma forma sobrecarregada de um método existente.
javax.print.attribute.standard.DialogOwner Esta é uma nova classe no JDK 11 e é uma classe de atributos usada para suportar solicitações de impressão ou personalização de páginas a serem exibidas na parte superior de todas as janelas ou em uma janela específica. javax.swing.DefaultComboBoxModel javax.swing.DefaultListModel
  • void addAll (Collection): Adiciona todos os elementos presentes na coleção.

  • void addAll (int, Collection): Adiciona todos os elementos presentes na coleção, começando no índice especificado.
javax.swing.ListSelectionModel
  • int [] getSelectedIndices (): Retorna uma matriz de todos os índices selecionados no modelo selecionado em ordem crescente.

  • int getSelectedItemsCount (): Retorna o número de itens selecionados.
jdk.jshell.EvalException
  • shell.JShellException getCause (): Retorna o motivo jogável no cliente de execução apresentado por esta EvalException ou nulo se o motivo não existir ou for desconhecido.

Recursos para não desenvolvedores do Java 11

[181] Controle de acesso baseado em ninho Java e outras linguagens suportam classes aninhadas por meio de classes internas. Para que isso funcione, o compilador deve realizar alguns truques. Por exemplo:
public class Outer {
    private int outerInt;

     class Inner {
       public void printOuterInt() {
         System.out.println("Outer int = " + outerInt);
       }
     }
   }
O compilador modifica isso para produzir algo parecido com o seguinte antes de compilar:
public class Outer {
      private int outerInt;

      public int access$000() {
        return outerInt;
      }

    }


    class Inner$Outer {

      Outer outer;

      public void printOuterInt() {
        System.out.println("Outer int = " + outer.access$000());
      }
    }
Embora logicamente a classe interna faça parte do mesmo código que a classe externa, ela é compilada como uma classe separada. Portanto, esta operação requer um método de junção sintético que deve ser criado pelo compilador para fornecer acesso ao campo privado da classe externa. Este PEC introduz o conceito de ninhos, onde dois membros do mesmo ninho (Externo e Interno em nosso exemplo) são companheiros de nidificação. Dois novos atributos são definidos para o formato de arquivo de classe: NestHost e NestMembers . Essas alterações são úteis para outras linguagens que suportam classes aninhadas e bytecode. Esta função introduz três novos métodos para java.lang.Class : Classe getNestHost () Class [] getNestMembers () boolean isNestmateOf (Class) [309] Constantes dinâmicas de arquivo de classe Este JEP descreve uma extensão para o formato de arquivo de classe para suportar o novo formulário de pool persistente CONSTANT_Dynamic. A ideia de uma constante dinâmica parece um oxímoro, mas essencialmente você pode pensar nela como um valor final em Java 11. O valor de uma constante de pooling não é definido em tempo de compilação (ao contrário de outras constantes), mas usa um bootstrap método para determinar o valor no lead time. Portanto o valor é dinâmico, mas como seu valor é definido apenas uma vez, também é constante. Este recurso é voltado principalmente para pessoas que desenvolvem novas linguagens e compiladores que irão gerar bytecodes e arquivos de classe como saída para execução na JVM. [315] Melhorar os intrínsecos do Aarch64 Este JEP foi proposto pela comunidade Red Hat. A JVM agora pode usar instruções mais especializadas disponíveis no conjunto de instruções Arm 64. Em particular, isso melhora o desempenho dos métodos , sin ()e cos ()da log ()classe java.lang.Math . [318] Epsilon: um coletor de lixo autônomo Assim como no JEP 315 , você pode agradecer à Red Hat pela introdução do coletor de lixo Epsilon. O Epsilon é incomum porque na verdade não coleta lixo! Quando novos objetos são criados, ele aloca memória, se necessário, mas não recupera o espaço ocupado por objetos não registrados. “ Qual é o objetivo? ", - você pergunta. Acontece que essa “coleta de lixo” tem duas utilidades:
  1. Em primeiro lugar, este coletor de lixo foi projetado para garantir que novos algoritmos de GC sejam avaliados em termos de impacto no desempenho. A ideia é executar um exemplo de aplicação com Epsilon e gerar um conjunto de métricas. O novo algoritmo de coleta de lixo é habilitado, os mesmos testes são executados e os resultados são comparados.

  2. Para tarefas muito curtas (pense em funções sem servidor na nuvem), onde você pode garantir que não excederá a memória alocada para o heap. Isso pode melhorar o desempenho eliminando a sobrecarga (incluindo a coleta de estatísticas necessárias para decidir se o coletor deve ser executado) no código do aplicativo. Se o espaço de heap estiver esgotado, a JVM poderá estar configurada incorretamente de uma das três maneiras:
    • Normal é chamado OutOfMemoryError.
    • Execute uma redefinição de heap
    • O disco rígido da JVM falhou e pode estar executando outra tarefa (como iniciar um depurador).
[328]: Flight Recorder Flight Recorder é uma estrutura de aquisição de dados de baixo nível para a JVM. Antes do JDK 11, esse era um recurso comercial no binário Oracle JDK. A Oracle agora está eliminando as diferenças funcionais entre o Oracle JDK e uma versão do OpenJDK. Aqui está o que o Flight Recorder faz :
  • Fornece uma API para produzir e consumir dados como eventos
  • Fornece um mecanismo de buffer e formato de dados binários
  • Permite customização e filtragem de eventos
  • Fornece eventos para SO, JVM HotSpot e bibliotecas JDK
Existem dois novos módulos aqui: jdk.jfr e jdk.management.jfr . [329] Algoritmos criptográficos ChaCha20 e Poly1305 Este JEP trata da atualização das cifras usadas pelo JDK. Este caso implementa os algoritmos de criptografia ChaCha20 e ChaCha20-Poly1305 conforme especificado na RFC 7539. ChaCha20 é uma cifra de fluxo relativamente nova que pode substituir a cifra RC4 mais antiga e insegura . [333] ZGC: Um coletor de lixo escalonável de baixa latência Um coletor de lixo experimental escalonável de baixa latência. Projetado para uso com aplicativos que exigem heap grande (multigigabyte) e baixa latência. Ele usa um heap de geração única e faz a maior parte (mas não todas) da coleta de lixo funcionar ao mesmo tempo que o aplicativo. [332] Transport Layer Security (TLS) 1.3 TLS 1.3 (RFC 8446) é um patch importante para o protocolo de segurança da camada de transporte TLS que fornece melhorias significativas de segurança e desempenho em relação às versões anteriores. O JDK agora oferece suporte a esta versão do protocolo. O material é baseado em artigo de Simon Ritter e documentação oficial .
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION