Clique se gostar do projeto. Suas contribuições são calorosamente bem-vindas.
Multithreading
Coleções
Conectividade de banco de dados Java (JDBC)
Programas Java
Métodos de string Java
Páginas do servidor Jacarta (JSP)
Servlets
Perguntas de múltipla escolha sobre Java
Padrão de Design Java
Hibernar
Noções básicas do Spring Framework
Introdução
Arquitetura Java
Tipos de dados Java
Métodos Java
Programação funcional Java
Expressões Java Lambda
Aulas Java
Construtores Java
Matriz Java
Sequências Java
Reflexão Java
Fluxos Java
Expressões regulares Java
Manipulação de arquivos Java
Exceções Java
Herança Java
Substituição de método Java
Polimorfismo Java
Abstração Java
Interfaces Java
Encapsulamento Java
Genéricos Java
Variado
Métodos de interface por padrão;
Expressões lambda;
Interfaces funcionais;
Referências a métodos e construtores;
Anotações repetíveis
Anotações sobre tipos de dados;
Reflexão para parâmetros de métodos;
API Stream para trabalhar com coleções;
Ordenação paralela de arrays;
Nova API para trabalhar com datas e horas;
Novo mecanismo JavaScript Nashorn;
Adicionadas várias novas classes para operação segura de thread;
Adicionada uma nova API para Calendar
e Locale
;
Adicionado suporte para Unicode 6.2.0;
Adicionada uma classe padrão para trabalhar com Base64;
Adicionado suporte para aritmética não assinada;
Construtor aprimorado java.lang.String(byte[], *)
e desempenho do método java.lang.String.getBytes()
;
Uma nova implementação AccessController.doPrivileged
que permite definir um subconjunto de privilégios sem ter que verificar todos * os outros níveis de acesso;
Os algoritmos baseados em senha tornaram-se mais robustos;
Adicionado suporte para indicação de nome de servidor SSL/TLS (NSI) no servidor JSSE;
Armazenamento de chaves aprimorado (KeyStore);
Adicionado algoritmo SHA-224;
Ponte JDBC removida - ODBC;
PermGen é removido, o método de armazenamento de metadados de classes é alterado;
Capacidade de criar perfis para a plataforma Java SE, que incluem não toda a plataforma, mas parte dela;
Ferramentas
Adicionado utilitário jjs
para usar JavaScript Nashorn;
O comando java
pode executar aplicativos JavaFX;
Adicionado utilitário jdeps
para análise de arquivos .class.
↥ voltar ao topo
Nashorn é um mecanismo JavaScript desenvolvido em Java pela Oracle. Projetado para fornecer a capacidade de incorporar código JavaScript em aplicativos Java. Comparado ao Rhino, que é apoiado pela Mozilla Foundation, o Nashorn oferece desempenho de 2 a 10 vezes melhor, pois compila código e transfere bytecode para a máquina virtual Java diretamente na memória. Nashorn pode compilar código JavaScript e gerar classes Java que são carregadas com um carregador especial. Também é possível chamar código Java diretamente do JavaScript.
↥ voltar ao topo
jjs
- Este é um utilitário de linha de comando que permite executar programas JavaScript diretamente no console.
↥ voltar ao topo
Em Java, existem três maneiras diferentes de ler a entrada do usuário no ambiente de linha de comando (console).
1. Usando a classe Buffered Reader:
Este método é usado agrupando o System.in (fluxo de entrada padrão) em um InputStreamReader que é agrupado em um BufferedReader, podemos ler a entrada do usuário na linha de comando.
/** * Classe de leitor com buffer */import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Test { public static void main(String[] args) throws IOException { // Enter dados usando BufferReader BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); // Lendo dados usando readLine String name = reader.readLine(); // Imprimindo a linha de leitura System.out.println(name); } }
2. Usando a classe Scanner:
O principal objetivo da classe Scanner é analisar tipos primitivos e strings usando expressões regulares, porém também pode ser usada para ler a entrada do usuário na linha de comando.
/** * Classe Scanner */import java.util.Scanner;class GetInputFromUser { public static void main(String args[]) { // Usando o Scanner para obter entrada do usuário Scanner in = new Scanner(System.in); String s = in.nextLine(); System.out.println("Você digitou a string " + s); int a = in.nextInt(); System.out.println("Você digitou o número inteiro " + a); float b = in.nextFloat(); System.out.println("Você digitou float " + b); } }
3. Usando classe de console:
Tem se tornado a forma preferida de ler a entrada do usuário na linha de comando. Além disso, pode ser usado para ler entradas semelhantes a senhas sem repetir os caracteres inseridos pelo usuário; a sintaxe da string de formato também pode ser usada (como System.out.printf() ).
/** * Console Class */public class Sample { public static void main(String[] args) { // Usando o Console para inserir dados do usuário String name = System.console().readLine(); System.out.println(nome); } }
↥ voltar ao topo
O comando javap exibe informações sobre os campos, construtores e métodos presentes em um arquivo de classe. O comando javap (também conhecido como Java Disassembler) desmonta um ou mais arquivos de classe.
/** * Java Disassembler */class Simple { public static void main(String args[]) { System.out.println("Olá Mundo"); } }
cmd> javap Simples.class
Saída
Compilado da classe ".java" Simple { Simples(); public static void main(java.lang.String[]); }
↥ voltar ao topo
System.out::println
? A expressão especificada ilustra a passagem de uma referência a um método estático de uma classe println()
System.out
.
↥ voltar ao topo
Os fluxos podem ser sequenciais e paralelos. As operações em fluxos sequenciais são realizadas em um thread de processador, em fluxos paralelos - usando vários threads de processador. Fluxos paralelos usam o fluxo compartilhado ForkJoinPool
por meio do método estático ForkJoinPool.commonPool()
. Nesse caso, se o ambiente não for multi-core, o fluxo será executado como sequencial. Na verdade, o uso de fluxos paralelos se resume ao fato de que os dados nos fluxos serão divididos em partes, cada parte será processada em um núcleo de processador separado e, no final, essas partes serão conectadas e as operações finais serão executadas em eles.
Você também pode usar o método de interface parallelStream()
para criar um fluxo paralelo da coleção Collection
.
Para tornar um fluxo sequencial regular paralelo, você deve chamar o método Stream
no objeto parallel()
. O método isParallel()
permite descobrir se o fluxo é paralelo.
Utilizando os métodos parallel()
e sequential()
é possível determinar quais operações podem ser paralelas e quais apenas sequenciais. Você também pode criar um fluxo paralelo a partir de qualquer fluxo sequencial e vice-versa:
coleção .fluxo () .peek (...) // a operação é sequencial .paralelo() .map (...) // a operação pode ser realizada em paralelo, .sequencial() .reduce (...) // operação é sequencial novamente
Via de regra, os elementos são transferidos para o fluxo na mesma ordem em que são definidos na fonte de dados. Ao trabalhar com fluxos paralelos, o sistema preserva a sequência de elementos. Uma exceção é um método forEach()
que pode gerar elementos em ordem aleatória. E para manter a ordem é necessário aplicar o método forEachOrdered()
.
Critérios que podem afetar o desempenho em fluxos paralelos:
Tamanho dos dados - quanto mais dados, mais difícil será separá-los primeiro e depois combiná-los.
O número de núcleos do processador. Teoricamente, quanto mais núcleos houver em um computador, mais rápido o programa funcionará. Se a máquina tiver um núcleo, não faz sentido usar threads paralelos.
Quanto mais simples for a estrutura de dados com a qual o fluxo trabalha, mais rápidas serão as operações. Por exemplo, os dados de ArrayList
são fáceis de usar, pois a estrutura desta coleção assume uma sequência de dados não relacionados. Mas uma coleção do tipo LinkedList
não é a melhor opção, pois em uma lista sequencial todos os elementos estão conectados com anterior/próximo. E esses dados são difíceis de paralelizar.
As operações com tipos primitivos serão mais rápidas do que com objetos de classe.
É altamente recomendável que você não use fluxos paralelos para operações longas (por exemplo, conexões de rede), pois todos os fluxos paralelos funcionam com um ForkJoinPool
, tais operações longas podem interromper todos os fluxos paralelos na JVM devido à falta de threads disponíveis na piscina, etc. fluxos paralelos devem ser usados apenas para operações curtas em que a contagem dura milissegundos, mas não para aquelas em que a contagem pode durar segundos e minutos;
Salvar ordem em fluxos paralelos aumenta os custos de execução, e se a ordem não for importante, é possível desabilitar seu salvamento e assim aumentar a produtividade usando uma operação intermediária unordered()
:
coleção.parallelStream() .classificado () .não ordenado () .collect(Coletores.toList());
↥ voltar ao topo
Java Virtual Machine (JVM) é uma especificação que fornece um ambiente de tempo de execução no qual o bytecode java (arquivos .class) pode ser executado. A JVM é a plataforma. A JVM atua como uma máquina ou processador “virtual”. A independência da plataforma Java consiste principalmente em sua Java Virtual Machine (JVM). A JVM torna isso possível porque está ciente dos comprimentos específicos das instruções e outras particularidades da plataforma (Sistema Operacional).
A JVM não é independente de plataforma. Java Virtual Machine (JVM) fornece o ambiente para executar o arquivo java (arquivo .class). Então, no final, depende do kernel e o kernel difere de sistema operacional (sistema operacional) para sistema operacional. A JVM é usada para traduzir o bytecode para a linguagem de máquina de um computador específico e também para executar as instruções de linguagem de máquina correspondentes.
↥ voltar ao topo
O compilador Just-In-Time (JIT) é um componente do ambiente de tempo de execução que melhora o desempenho de aplicativos Java compilando bytecodes para código de máquina nativo em tempo de execução.
Os programas Java consistem em classes que contêm bytecodes neutros em termos de plataforma que podem ser interpretados por uma JVM em muitas arquiteturas de computador diferentes. Em tempo de execução, a JVM carrega os arquivos de classe, determina a semântica de cada bytecode individual e executa o cálculo apropriado. O uso adicional de processador e memória durante a interpretação significa que um aplicativo Java tem um desempenho mais lento do que um aplicativo nativo. O compilador JIT ajuda a melhorar o desempenho de programas Java compilando bytecodes em código de máquina nativo em tempo de execução. O compilador JIT está habilitado por padrão. Quando um método é compilado, a JVM chama o código compilado desse método diretamente, em vez de interpretá-lo.
↥ voltar ao topo
O Java ClassLoader faz parte do Java Runtime Environment que carrega dinamicamente classes Java na Java Virtual Machine. O código Java é compilado em um arquivo de classe pelo compilador javac e a JVM executa o programa Java, executando códigos de bytes escritos no arquivo de classe. ClassLoader é responsável por carregar arquivos de classe do sistema de arquivos, rede ou qualquer outra fonte.
Tipos de ClassLoader:
1. Carregador de classes Bootstrap :
Ele carrega arquivos de classe JDK padrão de rt.jar e outras classes principais. Ele carrega arquivos de classe de jre/lib/rt.jar. Por exemplo, classe de pacote java.lang.
2. Carregador de classes de extensões :
Ele carrega classes das extensões JDK diretamente, geralmente no diretório JAVA_HOME/lib/ext
ou qualquer outro diretório como java.ext.dirs.
3. Carregador de classes do sistema :
Ele carrega classes específicas do aplicativo da variável de ambiente CLASSPATH. Ele pode ser definido ao invocar o programa usando as opções de linha de comando -cp ou classpath.
↥ voltar ao topo
1.JDK :
Java Development Kit é o componente principal do ambiente Java e fornece todas as ferramentas, executáveis e binários necessários para compilar, depurar e executar um programa Java.
2.JVM :
JVM é responsável por converter o código de bytes em código específico da máquina. A JVM também depende da plataforma e fornece funções Java básicas, como gerenciamento de memória, coleta de lixo, segurança, etc. A JVM é personalizável e podemos usar opções Java para personalizá-la, por exemplo, alocando memória mínima e máxima para JVM. A JVM é chamada de virtual porque fornece uma interface que não depende do sistema operacional subjacente e do hardware da máquina.
2.JRE :
Java Runtime Environment fornece uma plataforma para executar programas Java. JRE consiste em binários JVM e Java e outras classes para executar qualquer programa com sucesso.
↥ voltar ao topo
1. Espaço de pilha Java:
O espaço Java Heap é usado pelo Java Runtime para alocar memória para objetos e classes JRE . Sempre que criamos qualquer objeto, ele é sempre criado no espaço Heap.
A coleta de lixo é executada na memória heap para liberar a memória usada por objetos que não possuem nenhuma referência. Qualquer objeto criado no espaço heap tem acesso global e pode ser referenciado de qualquer lugar do aplicativo.
2. Memória de pilha Java:
Pilha em java é uma seção de memória que contém métodos , variáveis locais e variáveis de referência . Variáveis locais são criadas na pilha.
A memória da pilha é sempre referenciada na ordem LIFO (Last-In-First-Out). Sempre que um método é invocado, um novo bloco é criado na memória da pilha para o método armazenar valores primitivos locais e fazer referência a outros objetos no método.
Assim que o método termina, o bloco deixa de ser utilizado e fica disponível para o próximo método. O tamanho da memória da pilha é muito menor em comparação com a memória Heap.
Diferença:
Parâmetro | Memória de pilha | Espaço de pilha |
---|---|---|
Aplicativo | Stack é usado em partes, uma de cada vez durante a execução de um thread | Todo o aplicativo usa espaço Heap durante o tempo de execução |
Tamanho | Stack tem limites de tamanho dependendo do sistema operacional e geralmente é menor que Heap | Não há limite de tamanho no Heap |
Armazenar | Armazena apenas variáveis primitivas e referências a objetos criados no Heap Space | Todos os objetos recém-criados são armazenados aqui |
Ordem | Ele é acessado usando o sistema de alocação de memória Last-in First-out (LIFO) | Essa memória é acessada por meio de técnicas complexas de gerenciamento de memória que incluem a geração jovem, a geração antiga ou estável e a geração permanente. |
Vida | A memória da pilha só existe enquanto o método atual estiver em execução | O espaço de heap existe enquanto o aplicativo for executado |
Eficiência | Comparativamente, muito mais rápido para alocar quando comparado ao heap | Mais lento para alocar quando comparado à pilha |
Alocação/Desalocação | Esta memória é automaticamente alocada e desalocada quando um método é chamado e retornado respectivamente | O espaço de heap é alocado quando novos objetos são criados e desalocados pelo Gargabe Collector quando eles não são mais referenciados |
↥ voltar ao topo
JVM é um programa que pega o bytecode Java e converte o código de bytes (linha por linha) em código compreensível pela máquina. A JVM executa alguns tipos específicos de operações:
Carregamento de código
Verificação de código
Executando o código
Ele fornece ambiente de tempo de execução para os usuários
Tipos de áreas de memória alocadas pela JVM:
1. Classloader : Classloader é um subsistema de JVM usado para carregar arquivos de classe.
2. Área de classe (método) : A área de classe (método) armazena estruturas por classe, como o pool de constantes de tempo de execução, dados de campo e método, o código para métodos.
3. Heap : É a área de dados de tempo de execução na qual os objetos são alocados.
4. Pilha : Java Stack armazena frames. Ele contém variáveis locais e resultados parciais e desempenha um papel na invocação e retorno do método. Cada thread possui uma pilha JVM privada, criada ao mesmo tempo que o thread.
5. Registro do contador de programa : registro PC (contador de programa). Ele contém o endereço da instrução da máquina virtual Java que está sendo executada no momento.
6. Pilha de métodos nativos : contém todos os métodos nativos usados na aplicação.
↥ voltar ao topo
A conversão automática de tipos de dados primitivos em seu tipo Wrapper equivalente é conhecida como boxing e a operação oposta é conhecida como unboxing.
Exemplo: Autoboxing
/** * Autoboxing */class BoxingExample { public static void main(String args[]) { int a = 50; Inteiro a2 = novo Inteiro(a); // Boxe Inteiro a3 = 5; // Boxe System.out.println(a2 + " " + a3); } }
Exemplo: desembalagem
/** * Unboxing */class UnboxingExample { public static void main(String args[]) { Integer i = new Integer(50); int a = eu; System.out.println(a); } }
↥ voltar ao topo
1. Transitório:
O modificador transitório informa ao subsistema de serialização de objetos Java para excluir o campo ao serializar uma instância da classe. Quando o objeto for desserializado, o campo será inicializado com o valor padrão; ou seja, nulo para um tipo de referência e zero ou falso para um tipo primitivo.
Exemplo:
/** * Transiente */public transitório int limite = 55; // não persistirápublic int b; // persistirá
2. Volátil:
O modificador volátil informa à JVM que as gravações no campo devem sempre ser descarregadas de forma síncrona na memória e que as leituras do campo devem sempre ser lidas na memória. Isso significa que os campos marcados como voláteis podem ser acessados e atualizados com segurança em um aplicativo multithread sem usar sincronização nativa ou baseada em biblioteca padrão.
Exemplo:
/** * Volátil */public class MyRunnable implements Runnable { private volátil boolean ativo; public void run() { ativo = verdadeiro; enquanto (ativo) { } } public void stop() { ativo = falso; } }
↥ voltar ao topo
Uma afirmação permite testar a exatidão de quaisquer suposições feitas no programa. A asserção é obtida usando a instrução assert em Java.
Ao executar a afirmação, acredita-se que ela seja verdadeira. Se falhar, a JVM gera um erro chamado AssertionError
. É usado principalmente para fins de teste durante o desenvolvimento.
A instrução assert é usada com uma expressão booleana e pode ser escrita de duas maneiras diferentes.
// Primeira maneira de afirmar expressão; // Segunda maneira de afirmar expressão1 : expressão2;
Exemplo:
/** * Asserções */public class Exemplo { public static void main(String[] args) { int age = 14; afirmar idade <= 18: "Não é possível votar"; System.out.println("A idade do eleitor é " + idade); } }
↥ voltar ao topo
1. Variável Final:
Variáveis finais nada mais são do que constantes. Não podemos alterar o valor de uma variável final depois de inicializada.
Exemplo:
/** * Variável Final */class Demo { final int MAX_VALUE = 99; void meuMetodo() { MAX_VALUE = 101; } public static void main(String args[]) { Demo obj = new Demo(); obj.meuMetodo(); } }
Saída
Exceção no thread "principal" java.lang.Error: Problema de compilação não resolvido: O campo final Demo.MAX_VALUE não pode ser atribuído em iniciantesbook.com.Demo.myMethod(Details.java:6)em iniciantesbook.com.Demo.main(Details.java:10)
2. Variável final em branco:
Uma variável final que não é inicializada no momento da declaração é conhecida como variável final em branco. Devemos inicializar a variável final em branco no construtor da classe, caso contrário ocorrerá um erro de compilação (Erro: variable MAX_VALUE might not have been initialized
).
Exemplo:
/** * Variável final em branco */class Demo { // Variável final em branco final int MAX_VALUE; Demo() { // Deve ser inicializado no construtor MAX_VALUE = 100; } void meuMetodo() { System.out.println(MAX_VALUE); } public static void main(String args[]) { Demo obj = new Demo(); obj.meuMetodo(); } }
Saída
100
3. Método Final:
Um método final não pode ser substituído. O que significa que mesmo que uma subclasse possa chamar o método final da classe pai sem problemas, mas não pode substituí-lo.
Exemplo:
/** * Método Final */class XYZ { final void demo() { System.out.println("Método da Classe XYZ"); } }class ABC estende XYZ { void demo() { System.out.println("Método de classe ABC"); } public static void main(String args[]) { ABC obj = new ABC(); obj.demo(); } }
↥ voltar ao topo
Se um tipo primitivo ou uma string for definida como uma constante e o valor for conhecido em tempo de compilação, o compilador substituirá o nome da constante em todo o código por seu valor. Isso é chamado de constante de tempo de compilação.
A constante de tempo de compilação deve ser:
Declarado final
Primitivo ou String
Inicializado na declaração
Inicializado com expressão constante
Eles são substituídos por valores reais em tempo de compilação porque o compilador conhece seu valor antecipadamente e também sabe que ele não pode ser alterado durante o tempo de execução.
final privado int x = 10;
↥ voltar ao topo
especificadores/modificadores de acesso ajudam a restringir o escopo de uma classe, construtor, variável, método ou membro de dados.
Existem quatro tipos de modificadores de acesso disponíveis em java:
default
– Nenhuma palavra-chave é necessária, quando uma classe, construtor, variável, método ou membro de dados é declarado sem qualquer especificador de acesso, então ele tem escopo de acesso padrão, ou seja, acessível apenas dentro do mesmo pacote.
private
- quando declarado como private , o escopo de acesso é limitado dentro da classe envolvente.
protected
- quando declarado como protocted, o escopo de acesso é limitado ao fechamento de classes, subclasses do mesmo pacote e também de outros pacotes.
public
- quando declarado como público, acessível em qualquer parte do programa.
... /* variáveis de membro de dados */ String firstName="Pradeep"; /* escopo padrão */ protected isValid=true; /* escopo protegido */ private String otp="AB0392"; /* escopo privado */ public int id = 12334; /* escopo público */ ... ... /* funções de membro de dados */ String getFirstName(){ return this.firstName; } /* escopo padrão */ protected boolean getStatus(){this.isValid;} /* escopo protegido */ private void generateOtp(){ /* escopo privado */ this.otp = this.hashCode() << 16; }; public int getId(){ return this.id; } /* escopo público */ ... .../* classes internas */ classe A{} /* escopo padrão */ classe protegida B{} /* escopo protegido */ classe privada C{} /* escopo privado */ classe pública D{} /* escopo público */ ...
↥ voltar ao topo
Em Java, todos os métodos não estáticos são, por padrão, funções virtuais . Somente os métodos marcados com a palavra-chave final
, que não podem ser substituídos, juntamente com private methods
, que não são herdados, são não virtuais.
Exemplo: função virtual com interface
/** * A função applyBrakes() é virtual porque * funções em interfaces são projetadas para serem substituídas. **/interface Bicicleta { void applyBrakes(); }class ACMEBicycle implements Bicycle { public void applyBrakes() { // Aqui implementamos applyBrakes() System.out.println("Freios aplicados"); //função } }
↥ voltar ao topo
Um método nativo é um método Java (um método de instância ou um método de classe) cuja implementação também é escrita em outra linguagem de programação, como C/C++. Além disso, um método marcado como nativo não pode ter corpo e deve terminar com ponto e vírgula:
Principal.java:
classe pública Principal { public nativo int intMethod (int i); public static void main(String[] args) { System.loadLibrary("Main"); System.out.println(new Main().intMethod(2)); } }
Principal.c:
#include <jni.h>#include "Main.h"JNIEXPORT jint JNICALL Java_Main_intMethod( JNIEnv *env, jobject obj, jint i) { return i * i; }
Compilar e executar:
javac Main.javajavah -jni Maingcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux Main.cjava -Djava.library.path=. Principal
Saída
4
↥ voltar ao topo
Se um método for declarado como estático, ele será membro de uma classe e não pertencerá ao objeto da classe. Pode ser chamado sem criar um objeto da classe. Um método estático também tem o poder de acessar membros de dados estáticos da classe.
Existem algumas restrições impostas a um método estático
O método estático não pode usar membros de dados não estáticos ou invocar métodos não estáticos diretamente.
O this
e super
não podem ser usados em contexto estático.
O método estático pode acessar apenas dados do tipo estático (variável de instância do tipo estático).
Não há necessidade de criar um objeto da classe para invocar o método estático.
Um método estático não pode ser substituído em uma subclasse
Exemplo:
/** * Métodos estáticos */class Parent { static void display() { System.out.println("Super class"); } } public class Exemplo estende Parent { void display() // tentando substituir display() { System.out.println("Sub class"); } public static void main(String[] args) { Obj pai = new Exemplo(); obj.display(); } }
Isso gera um erro em tempo de compilação. A saída é a seguinte -
Exemplo.java:10: erro: display() no exemplo não pode substituir display() em Parentvoid display() // tentando substituir display() ^ método substituído é erro estático1
↥ voltar ao topo
Qual é a estrutura e os recursos do uso de uma expressão lambda? Um lambda é um conjunto de instruções que podem ser separadas em uma variável separada e então chamadas repetidamente em vários locais do programa.
A base da expressão lambda é o operador lambda , que representa a seta ->
. Este operador divide a expressão lambda em duas partes: o lado esquerdo contém uma lista de parâmetros da expressão e o lado direito representa o corpo da expressão lambda, onde todas as ações são executadas.
A expressão lambda não é executada por si só, mas forma a implementação do método definido na interface funcional. É importante que a interface funcional contenha apenas um único método sem implementação.
interface Operacional { int calcular (int x, int y); }public static void main ( String [] args) { Operação operacional = (x, y) - > x + y; int resultado = operação.calcular(10, 20); System.out.println (resultado); //30}
Na verdade, as expressões lambda são, de certa forma, uma forma abreviada de classes anônimas internas que foram usadas anteriormente em Java.
Expressões lambda de execução diferida - são definidas uma vez em um local do programa, são chamadas se necessário, quantas vezes e em qualquer local do programa.
Os parâmetros da expressão lambda devem corresponder em tipo aos parâmetros do método de interface funcional:
operação = ( int x, int y) - > x + y;// Ao escrever a própria expressão lambda, o tipo de parâmetro não pode ser especificado: (x, y) - > x + y;// Se o método não aceita nenhum parâmetro, então os colchetes vazios são escritos, por exemplo: () - > 30 + 20 ;// Se o método aceita apenas um parâmetro, então os colchetes podem ser omitidos: n - > n * n;
As expressões lambda finais não precisam retornar nenhum valor.
interface Imprimível { void print(String s); } public static void main (String [] args) {Impressora imprimível = s -> System.out.println(s); impressora.print("Olá, mundo"); }// _Bloco lambda-expressões_ são cercados por chaves. As expressões lambda modulares podem ser usadas dentro de blocos aninhados, loops, `projetar a instrução if `` switch ', criar variáveis, e assim por diante. d. Se você bloquear uma expressão lambda deve retornar um valor, ela se aplica explicitamente à `instrução de retorno ': Operação operacional = ( int x, int y) - > { se (y == 0) { retornar 0; } else { retornar x / y; } };
Passando uma expressão lambda como parâmetro de método
interface Condição {boolean isAppropriate (int n); }private static int sum (int [] números, condição condição) { int resultado = 0; for (int i: números) { if (condição.isAppropriate(i)) { resultado + = i; } } retornar resultado; }public static void main ( String [] args) { System.out.println(sum ( new int [] { 0 , 1 , 0 , 3 , 0 , 5 , 0 , 7 , 0 , 9 }, (n) - > n ! = 0 )); }
↥ voltar ao topo
O acesso a variáveis de escopo externas a partir de uma expressão lambda é muito semelhante ao acesso a partir de objetos anônimos.
variáveis locais imutáveis (efetivamente finais - não necessariamente marcadas como finais);
campos de classe
variáveis estáticas.
Os métodos padrão da interface funcional implementada não podem ser acessados dentro da expressão lambda.
↥ voltar ao topo
Se o método existente na classe já faz tudo o que é necessário, então você pode usar o mecanismo de referência de método (referência de método) para passar esse método diretamente. O resultado será exatamente o mesmo que no caso de definir uma expressão lambda que chama este método.
Exemplo:
interface privada Mensurável { public int length (String string); }public static void main ( String [] args) { Mensurável a = String::length; System.out.println(a.length("abc")); }
As referências de métodos são potencialmente mais eficientes do que usar expressões lambda. Além disso, eles fornecem ao compilador melhores informações sobre o tipo, e se você puder escolher entre usar uma referência a um método existente ou usar uma expressão lambda, você deve sempre usar uma referência de método.
↥ voltar ao topo
no método estático;
método por instância;
para o construtor.
↥ voltar ao topo
A classe Nested Inner pode acessar qualquer variável de instância privada da classe externa. Como qualquer outra variável de instância, podemos ter modificador de acesso privado, protegido, público e modificador padrão.
Exemplo:
/** * Classe interna */classe externa { classe Interna { exibição pública vazia() { System.out.println("Em um método de classe aninhada"); } } } classe Principal { public static void main(String[] args) { Outer.Inner in = new Outer().new Inner(); in.show(); } }
Uma subclasse é uma classe que herda um método ou métodos de uma superclasse.
Exemplo:
/** * Subclasse */class Carro { //...} class HybridCar estende Carro { //...}
↥ voltar ao topo
1. Carregamento de classe estática:
A criação de objetos e instâncias usando new
palavra-chave é conhecida como carregamento de classe estática. A recuperação da definição de classe e instanciação do objeto é feita em tempo de compilação.
Exemplo:
/** * Carregamento de classe estática */class TestClass { public static void main(String args[]) { TestClass tc = new TestClass(); } }
2. Carregamento dinâmico de classe:
Carregar classes usa o método Class.forName()
. O carregamento dinâmico da classe é feito quando o nome da classe não é conhecido em tempo de compilação.
Exemplo:
/** * Carregamento Dinâmico de Classe */Class.forName (String className);
↥ voltar ao topo
1. Classe de tempo de execução:
A classe java.lang.Runtime é uma subclasse da classe Object, fornece acesso ao sistema de tempo de execução Java. As informações de tempo de execução, como disponibilidade de memória, chamada do coletor de lixo, etc.
Exemplo:
/** * Classe de tempo de execução */public class RuntimeTest { classe estática Mensagem estende Thread { public void run() { System.out.println("Exit"); } } public static void main(String[] args) { tente { Runtime.getRuntime().addShutdownHook(new Message()); System.out.println("Programa iniciado..."); System.out.println("Aguarde 5 segundos..."); Thread.sleep(5000); System.out.println("Programa encerrado..."); } catch (Exceção e) { e.printStackTrace(); } } }
2. Classe do sistema:
O objetivo da classe do sistema é fornecer acesso aos recursos do sistema. Ele contém acessibilidade à entrada padrão, saída independente, fluxos de saída de erro, horário atual em milis, encerrar o aplicativo etc.
↥ de volta ao topo
1. Usando nova palavra -chave:
Objeto myObject = new MyObject ();
2. Usando classe.ForName ():
MyObject Object = (myObject) classe.ForName ("subin.rnd.myObject"). NewInstance ();
3. Usando clone ():
MyObject OUTROBJECT = new MyObject (); MyObject Object = (myObject) outroObject.Clone ();
4. Usando a deserivação do objeto:
ObjectInputStream unstrate = new ObjectInputStream (AninputStream); MyObject Object = (MyObject) Instream.readObject ();
↥ de volta ao topo
Objetos imutáveis são objetos que não mudam. Um objeto imutável Java deve ter que todos os seus campos sejam campos finais internos e privados. Não deve implementar nenhum setters. Precisa de um construtor que tenha um valor para cada campo.
Criando um objeto imutável:
Não adicione nenhum método de setter
Declare todos os campos finais e privados
Se um campo é um objeto mutável, crie cópias defensivas para métodos getter
Se um objeto mutável passado para o construtor deverá ser atribuído a um campo, crie uma cópia defensiva dele
Não permita que as subclasses substituam os métodos.
/** * Objeto imutável */classe pública DatEContainer {data final da data final; public DATEContainer () {this.date = new Date (); } public date getDate () {return new Date (date.gettime ()); } }
↥ de volta ao topo
Classe imutável significa que, uma vez criado um objeto, não podemos alterar seu conteúdo. Em Java, todas as classes do invólucro (como integer, booleano, byte, curta) e a classe de cordas são imutáveis.
Regras para criar classes imutáveis:
A classe deve ser declarada como final
Os membros de dados da classe devem ser declarados como finais
Um construtor parametrizado
Método getter para todas as variáveis nele
Sem setters
/** * Classe imutável */Public Final Class Funcionário {Final String PancardNumber; funcionário público (string pancardNumber) {this.pancardNumber = PancardNumber; } public String getPancardNumber () {return PancardNumber; } }
↥ de volta ao topo
O Bootstrap Classloader é repsonsible para carregar arquivos de classes JDK padrão do RT.Jar e é pai de todos os carregadores de classe em Java. Existem três tipos de carregador de classe interno em Java:
1. Carregador de classe de bootstrap: carrega classes internas do JDK, normalmente carrega rt.jar e outras classes principais, por exemplo, java.lang.* Classes de pacotes
2 Extensões Classe Loader: Ele carrega classes do diretório JDK Extensions, geralmente $ java_home/lib/ext.
3. Carregador da classe do sistema: ele carrega classes do caminho de classe atual que pode ser definido ao invocar um programa usando opções de linha de comando -CP ou -ClassPath.
/** * classloader */importar java.util.logging.level; importar java.util.logging.logger; public class ClassLoadestest {public static void main (string args []) {tente {// Printing Classloader deste sistema de classe .out.println ("ClassLoader:" + ClassLoadestest.class.getclassloader ()); // Tentando carregar explicitamente esta classe novamente usando classe de carregador de extensão. } catch (classNotFoundException Ex) {Logger.getLogger (classeLloadRestest.class.getName ()). log (Level.severe, null, ex); } } }
↥ de volta ao topo
Maneiras diferentes de criar um objeto em java
Usando uma nova palavra -chave:
classe ObjectCreationExample {String proprietário; } classe pública mainClass {public static void main (string [] args) {// aqui estamos criando objeto de JBT usando o novo KeywordObjectCreationExample OBJ = new ObjectCreationExample (); } }
Usando a nova instância (reflexão)
classe CreateObjectClass {static int j = 10; createObjectClass () {i = j ++; } int i; @OverridePublic String tostring () {return "valor de i:" + i; } } classe mainClass {public static void main (string [] args) {try {class cLs = class.ForName ("CreateObjectClass"); createObjectClass obj = (CreateObjectClass) cls.NewInstance (); CreateObjectClass obj1 = (CreateBjast) cls.newinStance (); (); System.out.println (obj); System.out.println (obj1); } catch (classNotFoundException e) {e.printStackTrace (); } catch (instantiationException e) {e.printStackTrace (); } catch (ilegalAccessException e) {E.PrintStackTrace (); } } }
Usando clone:
classe CreateObjectWithClone implementa cloneable {@OverRideProtected Object clone () lança clonenotsupportedException {return super.clone (); } int i; static int j = 10; createObjectWithClone () {i = j ++; } @OverridePublic string tostring () {return "valor de i:" + i; } } classe mainClass {public static void main (string [] args) {createObjectWithClone obj1 = new CreateObjectWithClone (); System.out.println (obj1); Try {CreateBjectWithClOne obj2 = (CreateObjectWithClone) obj1.clone (); System.out. println (obj2); } catch (clonenotsupportEdException e) {e.printStackTrace (); } } }
Usando classe de classe
classe CreateObjectWithClassLoader {static int j = 10; createObjectWithClassLoader () {i = j ++; } int i; @OverridePublic String tostring () {return "valor de i:" + i; } } classe pública mainClass {public static void main (string [] args) {createObjectWithClassLoader obj = null; tente {obj = (createObjectWithClassLoader) new mainClass (). getClass () .getClassLoader (). LoadClass ("CreateObjectWithClassLoader"). NewInstance (); // Nome de classe totalmente qualificado deve ser usado. } catch (instantiationException e) {e.printStackTrace (); } catch (ilegalAccessException e) {E.PrintStackTrace (); } catch (classNotFoundException e) {e.printStackTrace (); } System.out.println (obj); } }
↥ de volta ao topo
A classe de objeto é a classe pai de todas as classes em Java por padrão.
Método | Descrição |
---|---|
Classe final pública getclass () | Retorna o objeto de classe de classe desse objeto. A aula pode ser usada ainda para obter os metadados desta classe. |
public int hashcode () | Retorna o número do HashCode para este objeto. |
BOOLEANOS PÚBLICOS EQUILES (Objeto OBJ) | compara o objeto dado a este objeto. |
Objeto protegido clone () lança clonenotsupportedException | Cria e retorna a cópia exata (clone) deste objeto. |
public string tostring () | Retorna a representação da string deste objeto. |
Public Final Void Notify () | Acorde um único thread, aguardando o monitor deste objeto. |
Public Final Void NotifyAll () | Acorda todos os threads, aguardando o monitor deste objeto. |
Public Final Void Wait (longo tempo limite) lança interruptedException | faz com que o thread atual aguarde os milissegundos especificados, até que outro thread notifique (Invokes notify () ou notifyAll () método). |
Public Final Void Wait (longo tempo de tempo, int nanos) lança interruptedException | faz com que o encadeamento atual aguarde os milissegundos e nanossegundos especificados, até que outro thread notifique (o Método Notify () ou notifyAll ()). |
Public Final Void Wait () lança interruptedException | faz com que o thread atual aguarde, até que outro thread notifique (o Invokes notify () ou notifyAll () método). |
Void protegido Finalize () joga lançável | é chamado pelo coletor de lixo antes que o objeto esteja sendo coletado de lixo. |
↥ de volta ao topo
Um valor opcional Optional
é um contêiner para um objeto que pode ou não conter um valor null
. Esse invólucro é um meio de prevenção conveniente