0% acharam este documento útil (0 voto)
9 visualizações57 páginas

Guia de Desenvolvimento Java (Reparado)

A apostila de Desenvolvimento JAVA, escrita por Benevanio Santos, apresenta uma introdução à linguagem Java, suas versões e conceitos fundamentais, como a JVM e tipos de variáveis. O autor compartilha sua jornada pessoal desde o sertão do Agreste Sergipano até se tornar um desenvolvedor de software, destacando a importância da tecnologia para melhorar a vida das pessoas. O material é voltado para iniciantes e visa inspirar e facilitar o aprendizado da programação em Java.

Enviado por

benevanio santos
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
9 visualizações57 páginas

Guia de Desenvolvimento Java (Reparado)

A apostila de Desenvolvimento JAVA, escrita por Benevanio Santos, apresenta uma introdução à linguagem Java, suas versões e conceitos fundamentais, como a JVM e tipos de variáveis. O autor compartilha sua jornada pessoal desde o sertão do Agreste Sergipano até se tornar um desenvolvedor de software, destacando a importância da tecnologia para melhorar a vida das pessoas. O material é voltado para iniciantes e visa inspirar e facilitar o aprendizado da programação em Java.

Enviado por

benevanio santos
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 57

Apostila para Desenvolvimento JAVA

AUTOR: BENEVANIO SANTOS


1

Sobre o autor

Olá, queridos leitores! Sejam todos bem-vindos a este livro de Java, um


espaço dedicado ao aprendizado e ao fascinante mundo da
programação. Antes de mergulharmos juntos nessa jornada, permitam-
me apresentar quem sou eu, o autor responsável por guiá-los por este
universo tecnológico.

Meu Nome: Benevanio

Meu nome é Benevanio, um entusiasta da tecnologia e um amante da


natureza. Entre amigos e colegas de trabalho, costumo ser
carinhosamente chamado de "Bene_Tesla", em homenagem ao grande
inventor e cientista Nikola Tesla, cuja criatividade e genialidade sempre
me inspiraram. Assim como Tesla, busco incessantemente inovar e
contribuir para o progresso da humanidade, embora eu o faça no campo
do desenvolvimento de software.

Meu primeiro emprego foi como Lavrador no Sertão do Agreste


Sergipano.

Minha trajetória de vida começou como lavrador no sertão do Agreste


Sergipano. Cresci entre as terras áridas, onde o sol escaldante castiga a
terra, mas onde também se encontra uma beleza singular na
simplicidade da vida rural. A experiência de trabalhar na roça desde
jovem me ensinou valores essenciais, como dedicação, perseverança e
gratidão pela natureza.
2

ilustração lavrador.

Objetivos Profissionais e a Paixão pelo Desenvolvimento de Software

Durante minha jornada como lavrador, uma chama curiosa despertou


em meu coração: a paixão pela tecnologia. Impulsionado pela vontade
de criar soluções inovadoras para os desafios enfrentados na minha
região, decidi embarcar no universo da programação. A partir desse
momento, encontrei meu propósito: utilizar o poder do desenvolvimento
de software para melhorar a vida das pessoas, impactando
positivamente suas realidades.

Um Pouco Sobre o Semi Árido do Agreste Sergipano

O sertão do Agreste Sergipano, situado na região semiárida do nordeste


brasileiro, é uma área de contrastes e rica cultura. As estações do ano
moldam o cenário, com períodos de intensa seca seguidos por breves e
revigorantes chuvas. A resiliência do povo sertanejo é admirável, assim
3

como a beleza das paisagens que se revelam quando a vegetação


ganha vida durante a época das chuvas.

Vista de porto da Folha Sergipe

Nessa terra de oportunidades e desafios, encontrei minha vocação no


desenvolvimento de software, buscando aplicar meu conhecimento para
levar inovação, educação e prosperidade às comunidades locais e além.

Estou animado em compartilhar com vocês meu conhecimento sobre


Java e o universo da programação. Espero que este livro seja uma fonte
inspiradora para seus estudos e uma ferramenta valiosa para
alcançarem seus objetivos no desenvolvimento de software.

Juntos, desbravamos os conceitos, as técnicas e as práticas que


envolvem o Java, e que este conhecimento possa ser tão transformador
quanto às chuvas que trazem vida ao sertão do Agreste.

Vamos em frente! O futuro da programação nos aguarda!

Benevanio (Bene Tesla).

Uma breve curiosidade sobre o nome Bene Tesla:

No decorrer de uma empolgante aula sobre correntes elétricas,


ministrada pelo professor Francisco Oliveira Filho, no ensino
4

fundamental, deparei-me com uma história fascinante que despertou


minha curiosidade. Em meio às explicações sobre circuitos e
eletricidade, o professor compartilhou com entusiasmo sobre a vida e o
trabalho do renomado inventor e cientista, Nikola Tesla. A história desse
visionário, suas contribuições inovadoras e sua genialidade no campo
da eletricidade e tecnologia deixaram uma marca profunda em minha
mente. Desde então, a paixão por descobrir mais sobre o notável Nikola
Tesla floresceu, impulsionando-me a explorar o mundo da ciência e
desenvolvimento de software, almejando seguir os passos dessa mente
brilhante. O ensinamento do professor Francisco Oliveira Filho e a
inspiradora história de Tesla ecoam até hoje em meu livro sobre Java,
servindo de combustível para minha jornada no universo da
programação e tornando a experiência de aprendizado ainda mais
cativante.

"O futuro pertence àqueles que acreditam na beleza de seus


sonhos.": Nikola Tesla
5

Introdução
Relatório apresentado para a matéria de linguagem orientada a objetos
do curso de engenharia de software, utilizando a linguagem de
programação Java.

O que é o JAVA?

A linguagem Java é uma linguagem de programação orientada a objetos


que pode ser usada em diversas plataformas e aplicações. Foi
desenvolvida pela Sun Microsystems em 1991 e atualmente é mantida
pela Oracle. Java permite escrever instruções para serem executadas
por computadores, controlando o hardware. Java é uma linguagem de
baixo nível com recursos de linguagens de alto nível. Java é diferente
das linguagens convencionais, pois não é compilada para código nativo.
6

JVM

A JVM, acrônimo para Java Virtual Machine (Máquina Virtual Java), é


um componente essencial para a compreensão de seu funcionamento.
Para ilustrar esse conceito, consideremos a seguinte analogia: suponha
que você realize uma compra no Mercado Livre (linguagem Java). Após
a conclusão da compra, a encomenda é encaminhada para a
transportadora (JVM) e, por fim, é entregue a você (Sistema
Operacional). A seguir, apresenta-se um exemplo detalhado dessa
relação:

Endereço 1
Mercado Endereço 2
Carteiros
Livre(compra) Endereço 3

O lema do Java é "Escreva uma vez e rode em qualquer lugar", para


7

alcançar esse objetivo, é necessário ter o JDK (Java Development Kit)


devidamente instalado na máquina. O JDK representa o "Kit de
Desenvolvimento Java" e é um conjunto de ferramentas que permite a
criação de jogos e programas para a plataforma Java. Ele abrange todo
o ambiente necessário para a concepção e execução de aplicativos
Java, inclusive o JRE (Java Runtime Environment), que é o ambiente de
execução instalado e responsável por fornecer o runtime necessário
para a aplicação ser executada.

Para que possamos entender um pouco mais sobre como o java


funciona veja a seguinte ilustração:

Percebe-se que a única alteração ocorreu no sistema operacional;


contudo, nossa linguagem continuou sendo a mesma. O Java, em
minha perspectiva, assemelha-se a uma mãe que tem vários filhos,
sendo capaz de cuidar de todos e amá-los de forma única. No mundo
do desenvolvimento, essa é a representação da linguagem Java - uma
figura materna para todos nós.

Versões do Java.

Para sermos desenvolvedores java temos que entender todas as


versões do java(Medo de código Legado,por isso que eu pesquisei
8

sobre esse capítulo), aqui vai uma breve linha do tempo sobre todas as
versões java até o momento das mais antigas até a mais recente,
incluindo uma breve explicação sobre as versões em LTS(Ve site da
Oracle).

1. **Java 1.0 (23 de janeiro de 1996):** O lançamento inicial do Java


introduziu a plataforma Java com seu ambiente de desenvolvimento e
suas bibliotecas básicas.

2. **Java 1.1 (19 de fevereiro de 1997):** Esta versão trouxe melhorias


significativas no desempenho e na funcionalidade, adicionando novas
APIs e a capacidade de trabalhar com bancos de dados.

3. **Java 1.2 (8 de dezembro de 1998):** Conhecido como "Java 2,"


trouxe melhorias significativas na plataforma, incluindo a adição do
pacote de coleções (java.util), eventos e o Java Foundation Classes
(JFC).

4. **Java 1.3 (8 de maio de 2000):** Essa versão focou em melhorias


de desempenho, adição de novas APIs e suporte para Bluetooth.

5. **Java 1.4 (6 de fevereiro de 2002):** Introduziu a máquina virtual


Java HotSpot, que melhorou significativamente o desempenho de
aplicações Java. Também incluiu suporte para XML e a API de Logging.

6. **Java 5 (Java 1.5) (30 de setembro de 2004):** Introduziu recursos


importantes, como Generics, Autoboxing, Enumerações e Anotações.

7. **Java 6 (Java 1.6) (11 de dezembro de 2006):** Aprimorou a


estabilidade e o desempenho, além de trazer melhorias na API de
desktop, como suporte a sistemas operacionais com aparência nativa.

8. **Java 7 (28 de julho de 2011):** Incluiu recursos notáveis, como


Switch com Strings, Melhorias no Gerenciamento de Recursos,
Invocação Dinâmica e suporte a múltiplos tipos genéricos.

9. **Java 8 (18 de março de 2014):** Uma das versões mais


significativas do Java, introduziu as Expressões Lambda, Streams, a
9

nova API de Data e Hora e melhorias na API de Coleções.

10. **Java 9 (21 de setembro de 2017):** Introduziu o sistema de


módulos Java (Jigsaw), que permite modularizar e organizar melhor o
código Java.

11. **Java 10 (20 de março de 2018):** Incluiu recursos menores,


como a inferência de tipos no Java, melhorias no compilador e na JVM.

12. **Java 11 (25 de setembro de 2018) - LTS:** Essa versão LTS


(Long-Term Support) trouxe melhorias no desempenho, aprimoramentos
no compilador, suporte ao HTTP/2 e a remoção de APIs obsoletas.

13. **Java 12 (19 de março de 2019):** Introduziu o Switch


Expressions (Preview) e melhorias no Garbage Collector.

14. **Java 13 (17 de setembro de 2019):** Incluiu recursos como Text


Blocks (Preview), melhorias no Garbage Collector e em Expressões
Switch.

15. **Java 14 (17 de março de 2020):** Introduziu Records (Preview),


padrões de texto e melhorias no Garbage Collector.

16. **Java 15 (15 de setembro de 2020):** Incluiu o recurso Sealed


Classes (Preview), melhorias no compilador e na JVM.

17. **Java 16 (16 de março de 2021):** Introduziu padrões de


matching, Records (Preview) e melhorias na plataforma.

18. **Java 17 (8 de setembro de 2021) - LTS:** A versão LTS mais


recente, com suporte a longo prazo, inclui recursos como melhorias no
Garbage Collector, novo suporte a padrões de matching e atualizações
em bibliotecas e APIs.

As versões normais são lançadas a cada seis meses, trazendo novos


recursos e melhorias incrementais. Já as versões LTS (Long-Term
Support) são lançadas a cada três anos e têm suporte estendido por um
10

período maior, garantindo atualizações de segurança e correções de


bugs por um período mais longo. As versões LTS são recomendadas
para aplicações e sistemas de longo prazo, enquanto as versões
normais são mais adequadas para projetos de curto prazo ou aqueles
que desejam aproveitar os recursos mais recentes rapidamente.

Primeiro Programa em Java.


Agora que já temos uma noção básica sobre o java, vamos criar o
nosso primeiro programa, vamos lá?
Primeiro nós criamos uma classe Main e dentro dela colocamos o
seguinte código:

public class Main {


public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

Passo a Passo Do Funcionamento de nosso Primeiro Programa:

1. `public class Main {`

Nesta linha, declaramos uma classe chamada "Main". Em Java, um


programa deve ter uma classe com um método `main` para que a
execução possa começar.

2. `public static void main(String[] args) {`

Aqui, definimos o método `main`. Esse é o ponto de entrada para a


execução do programa. O método `main` é sempre declarado como
`public` (acessível de fora da classe), `static` (pertence à classe, não a
uma instância específica) e `void` (não retorna nenhum valor).
OBS: Carinhosamente chamo de psvm.
11

3. `System.out.println("Hello, World!");`

Esta linha é o conteúdo do método `main`. O método `println` é usado


para imprimir a string "Hello, World!" na saída padrão (normalmente, a
saída é exibida no console).

4. `}`

Fecha o método `main`.

5. `}`

Fecha a classe "Main".

A execução do programa começará pelo método `main`, é a única


instrução presente nesse método é a impressão da mensagem "Hello,
World!" no console. Esse é um exemplo clássico de um programa em
Java que imprime essa mensagem icônica, sendo comumente utilizado
como o primeiro programa para os iniciantes em programação. Ele
serve como uma forma simples de verificar se o ambiente de
desenvolvimento está configurado corretamente e para garantir que o
código pode ser compilado e executado com sucesso.

Em resumo, o programa simplesmente imprime "Hello, World!" no


console quando executado.

Tipos de variáveis em java.

1. Variáveis Primitivas:
As variáveis primitivas armazenam diretamente o valor dos dados e são
geralmente usadas para armazenar tipos de dados simples. Existem 8
tipos primitivos em Java:

- `byte`: armazena valores inteiros de 8 bits. Exemplo:


byte myByte = 100;
12

- `short`: armazena valores inteiros de 16 bits. Exemplo:


short myShort = 2000;
- `int`: armazena valores inteiros de 32 bits. Exemplo:
int myInt = 50000;

- `long`: armazena valores inteiros de 64 bits. Adicione o sufixo 'L' ou 'l'


ao literal para indicar um valor long. Exemplo:
long myLong = 10000000000L;

- `float`: armazena valores de ponto flutuante de 32 bits. Adicione o


sufixo 'f' ou 'F' ao literal para indicar um valor float. Exemplo:
float myFloat = 3.14f;

- `double`: armazena valores de ponto flutuante de 64 bits. Exemplo:


double myDouble = 3.14159;
- `char`: armazena caracteres de 16 bits. Deve ser definido entre aspas
simples. Exemplo:
char myChar = 'A';

- `boolean`: armazena valores verdadeiros (`true`) ou falso (`false`).


Exemplo:
boolean isTrue = true;

2. Variáveis de Referência (Não Primitivas ou Literais):


As variáveis de referência não armazenam diretamente os dados, mas
referenciam objetos em memória. Essas variáveis são usadas para
armazenar instâncias de classes. Exemplos:

- Exemplo de String, uma classe que representa uma sequência de


caracteres.
String myString = "Hello, World!";
- Exemplo de um objeto Integer que encapsula um valor inteiro.
Integer myInteger = new Integer(42);
- Exemplo de um array de inteiros.
13

int[] myIntArray = {1, 2, 3, 4, 5};

Lembre-se de que as variáveis primitivas armazenam diretamente o


valor dos dados, enquanto as variáveis de referência armazenam
referências a objetos em memória.

Regras para a declaração de variáveis em java:


Em Java, existem algumas regras e convenções para declarar variáveis.
O padrão mais adequado é seguir as convenções de nomenclatura
estabelecidas pela comunidade Java. Isso ajuda a tornar o código mais
legível e compreensível por outros programadores. Aqui estão algumas
das regras e padrões mais comuns para a declaração de variáveis em
Java:

1. Nomes significativos: Escolha nomes que descrevam claramente o


propósito da variável. Evite nomes genéricos como `a`, `x`, `var`, etc.

2. CamelCase: Use a convenção CamelCase para nomes compostos,


começando com uma letra minúscula e maiúscula para cada palavra
subsequente. Exemplo: `nomeCompleto`, `idadeUsuario`,
`numeroDeAlunos`, etc.

3. Comece com letra minúscula: O nome da variável deve começar com


uma letra minúscula. Não é recomendado começar com números ou
símbolos.

4. Evite underscores em variáveis: Embora seja permitido, é mais


comum seguir a convenção CamelCase e evitar o uso de underscores
(_) em nomes de variáveis.

5. Evite palavras reservadas: Não utilize palavras reservadas da


linguagem Java, como `int`, `float`, `for`, etc., como nomes de variáveis.

6. Use nomes claros para constantes: Se estiver declarando uma


constante, use letras maiúsculas e palavras separadas por underscores.
Exemplo: `TAXA_JUROS`, `PI`, `IDADE_MINIMA`, etc.
14

7. Mantenha a consistência: Seja consistente ao nomear suas variáveis


em todo o código. Isso ajuda a tornar o código mais legível e fácil de
entender.

8. Evite abreviações excessivas: Embora algumas abreviações possam


ser aceitáveis, evite abreviar excessivamente os nomes das variáveis,
pois isso pode tornar o código menos claro.

Exemplo de declaração de variáveis seguindo as convenções:

int idadeUsuario = 30;


double alturaPessoa = 1.75;
boolean isAtivo = true;

String nomeCompleto = "João da Silva";


ArrayList<String> listaNomes = new ArrayList<>();
Person pessoa = new Person("Maria", 25);

final int LIMITE_MAXIMO = 100;


final double PI = 3.14159;
conceito retirado do livro clean code.

Seguir essas regras e padrões ajuda a tornar o código mais legível e


consistente, facilitando a colaboração em projetos e a manutenção do
código ao longo do tempo.

Construindo o nosso primeiro programa usando variáveis:

Primeiro vamos começar com a definição do que seria uma variável,


variáveis nada mais que pequenos bloco na memória do seu
computador capazes de armazenar(guardar) dados, para que isso fique
mais claro e de fácil entendimento vamos a um exemplo com uma
tabela, pensa que cada célula armazena um tipo de dado específico,o
cadastro de um usuário por exemplo.
15

variável tipo da variável valor da variável,


int age 25
String name João
boolean casado false

Nessa tabela podemos ver uma breve distinção do que seria uma
variável em nosso sistema,bem que tal vermos isso em java?

int age = 30;


String name = “joao”;
boolean casado = false;
System.out.println("Meu nome é "+ name + " eu tenho
" + age + "sou solteiro? " + casado);

Bem agora que nosso exemplo já está visível para você leitor, vamos
para a explicação do nosso código, tomei a liberdade para separar o
código em linhas para que possa facilitar o seu entendimento.

1. `int age = 30;`: Nesta linha, uma variável `age` é declarada e


inicializada com o valor inteiro `30`. A declaração `int` indica que a
variável é do tipo inteiro.

2. `String name =” joao”;`: Nesta linha, uma variável `name` é declarada


e inicializada com o valor `joao`.

3. `boolean casado = false;`: Nesta linha, uma variável `casado` é


declarada e inicializada com o valor booleano `false`. A declaração
`boolean` indica que a variável é do tipo booleano, ou seja, ela pode
armazenar apenas os valores `true` ou `false`.

4. `System.out.println("Meu nome é "+ name + " eu tenho " + age + "sou


solteiro? " + casado);`: Nesta linha, um comando `System.out.println` é
usado para imprimir uma mensagem no console.
16

- `"Meu nome é "`: É uma String literal que representa parte da


mensagem a ser impressa.
- `+ name +`: O operador `+` é usado para concatenar a variável
`name` (que deve conter uma String válida) à mensagem. Se `name`
contiver o valor `"João"`, então a parte da mensagem após essa
concatenação seria `"Meu nome é João"`.
- `" eu tenho "`: É outra String literal que será concatenada à
mensagem.
- `+ age +`: O operador `+` é usado novamente para concatenar o
valor da variável `age` à mensagem. Se `age` for `30`, então a parte da
mensagem após essa concatenação seria `" eu tenho 30"`.
- `"sou solteiro? "`: É outra String literal que será concatenada à
mensagem.
- `+ casado`: Finalmente, o valor da variável `casado` é concatenado à
mensagem. Se `casado` for `false`, a parte final da mensagem seria
"sou solteiro? false"`.

A saída final no console seria algo como:

```
Meu nome é João eu tenho 30 sou solteiro? false
```

Casting no java.

O casting de tipo, também conhecido como conversão de tipo, é um


conceito importante em Java (e em outras linguagens de programação)
que permite alterar o tipo de uma variável de dados de um tipo para
outro. Isso pode ser necessário quando você deseja atribuir uma
variável de um tipo a outra variável de outro tipo compatível ou quando
deseja realizar operações entre variáveis de tipos diferentes.

DADO INICIAL
17

Dado Final

Existem dois tipos de casting em Java:

1. Casting Implícito (Widening Casting):


- É quando ocorre a conversão de um tipo menor para um tipo maior.
- É feito automaticamente pelo compilador, pois não há risco de perda
de dados.
- Por exemplo, converter um `int` em `long`, `float` em `double`, `byte`
em `short`, entre outros.

Exemplo de casting implícito:

// casting implícito
int numInteiro = 10;
long numLongo = numInteiro;
System.out.println(numLongo);

2. Casting Explícito (Narrowing Casting):


- É quando ocorre a conversão de um tipo maior para um tipo menor.
18

- É feito manualmente pelo programador, pois há risco de perda de


dados (informação pode ser truncada).
- Para realizar o casting explícito, é necessário colocar o tipo desejado
entre parênteses antes da variável que será convertida.
- É importante ter cuidado ao fazer o casting explícito, pois se o valor
for maior que o limite do tipo de destino, pode ocorrer perda de dados.

Exemplo de casting explícito:

double a =10.5d;
int b = (int) a;
System.out.println(b);

Nesse exemplo, o valor 3.14159 é convertido para o inteiro 3. O que


ocorre é uma truncagem dos dígitos após o ponto decimal, resultando
na perda dos valores decimais.

É importante lembrar que nem todos os tipos podem ser convertidos


entre si. O casting só é permitido entre tipos compatíveis, ou seja, tipos
que tenham tamanho e precisão suficientes para conter os valores do
tipo original.

Ao utilizar o casting, é necessário estar ciente dos possíveis riscos de


perda de dados e garantir que a conversão seja feita de forma segura e
correta para evitar comportamentos indesejados no programa.

Entrada de dados.
Em Java, a entrada de dados é a forma pela qual um programa interage
com o usuário, permitindo que informações sejam fornecidas para o
programa durante a execução. Existem várias maneiras de realizar a
entrada de dados em Java, sendo as duas mais comuns:

1. Utilizando a classe `Scanner`:


A classe `Scanner` faz parte do pacote `java.util` e oferece métodos
para ler diferentes tipos de dados a partir de várias fontes, como o
19

teclado (entrada padrão) ou arquivos. Para utilizar o `Scanner`, você


precisa criar uma instância dele e especificar a fonte da entrada (por
exemplo, `System.in` para entrada pelo teclado).

Exemplo de entrada de um número inteiro usando o `Scanner`:


import java.util.Scanner;
public class App {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String name;
System.out.println("Digite seu nome: ");
name = sc.nextLine();
System.out.println("Bem vindo " + name + "!
");
sc.close();
}
}

2. Utilizando a classe `BufferedReader` em conjunto com


`InputStreamReader`:
A classe `BufferedReader` também pode ser utilizada para a entrada
de dados e permite ler linhas inteiras de texto do teclado. Para isso, é
necessário criar uma instância de `BufferedReader`, que pode ser
20

inicializada com um objeto `InputStreamReader` que representa a


entrada padrão (`System.in`).

Exemplo de entrada de uma linha de texto usando `BufferedReader`:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class EntradaDeDados {


public static void main(String[] args) throws
IOException {
BufferedReader reader = new
BufferedReader(new InputStreamReader(System.in));

System.out.print("Digite uma frase: ");


String frase= reader.readLine();

System.out.println("A frase digitada foi:


" + frase);

reader.close();
}
}

Ambos os métodos permitem que o programa obtenha informações


inseridas pelo usuário durante a execução e use essas informações
para realizar diversas tarefas ou cálculos. É importante ter em mente
que a entrada de dados deve ser tratada com cuidado para evitar erros
e exceções, e é sempre uma boa prática fechar os recursos de entrada
(Scanner ou BufferedReader) quando eles não são mais necessários.
21

Estruturas condicionais em java , IF ELSE.

Em Java, assim como em muitas outras linguagens de programação, as


estruturas condicionais são recursos que permitem ao programador
controlar o fluxo de execução do programa com base em condições
específicas. Isso significa que certos blocos de código só serão
executados se determinada condição for verdadeira, caso contrário,
serão ignorados ou outro bloco de código pode ser executado.

Existem duas estruturas condicionais principais em Java: o "if" (se) e o


"else" (senão). Além disso, existe a variante "else if" (senão, se) para
permitir múltiplas condições. Abaixo estão os principais formatos das
estruturas condicionais em Java:(OBS:COMO NO EXEMPLO
ANTERIOR USEI O SCANNER ACHO JUSTO UTILIZAR NESTE
TAMBÉM).

Scanner sc = new Scanner(System.in);


int horas;
System.out.println("Quantas horas?");
horas = sc.nextInt();
if (horas < 12) {
System.out.println("Bom dia");
} else if (horas < 18) {
System.out.println("Boa tarde");
} else {
System.out.println("Boa noite");
}
sc.close();
}

Esse código é um exemplo de um programa Java que utiliza a classe


`Scanner` para interagir com o usuário e, com base nas horas
informadas por ele, exibe uma saudação apropriada (bom dia, boa tarde
ou boa noite).
22

Vamos analisar o código passo a passo:

1. `Scanner sc = new Scanner(System.in);`: Aqui, uma instância da


classe `Scanner` é criada e associada à entrada padrão do sistema
(`System.in`). Isso permite que o programa leia dados inseridos pelo
usuário através do teclado.

2. `int horas;`: Declaração da variável `horas`, que será utilizada para


armazenar o valor de horas informado pelo usuário.

3. `System.out.println("Quantas horas?");`: Exibe uma mensagem no


console, pedindo ao usuário que insira o número de horas.

4. `horas = sc.nextInt();`: O programa utiliza o método `nextInt()` da


classe `Scanner` para ler um número inteiro digitado pelo usuário e
armazená-lo na variável `horas`.

5. `if (horas < 12) { ... }`: Aqui, começa a estrutura condicional. Se o
valor de `horas` for menor do que 12, o bloco de código dentro do `if`
será executado.

6. `System.out.println("Bom dia");`: Caso a condição do `if` seja


verdadeira (ou seja, `horas` for menor que 12), esta linha imprimirá
"Bom dia" no console.

7. `else if (horas < 18) { ... }`: Se a condição do `if` for falsa (ou seja,
`horas` não for menor que 12), o programa verificará se `horas` é menor
do que 18. Se for verdade, o bloco de código dentro do `else if` será
executado.

8. `System.out.println("Boa tarde");`: Caso a condição do `else if` seja


verdadeira (ou seja, `horas` for menor que 18), esta linha imprimirá "Boa
tarde" no console.

9. `else { ... }`: Se nenhuma das condições anteriores for verdadeira, ou


seja, se `horas` for 18 ou mais, o bloco de código dentro do `else` será
executado.
23

10. `System.out.println("Boa noite");`: Caso a condição do `else` seja


verdadeira (ou seja, `horas` for 18 ou mais), esta linha imprimirá "Boa
noite" no console.

11. `sc.close();`: Finalmente, o método `close()` é chamado na instância


do `Scanner` para liberar recursos associados à entrada do teclado.

Em resumo, esse programa solicita ao usuário um valor inteiro


representando o número de horas. Com base no valor inserido, ele
exibe uma saudação apropriada dependendo do intervalo horário: "Bom
dia" se for antes de 12, "Boa tarde" se for entre 12 e 18, e "Boa noite" se
for 18 ou depois disso.

Estruturas condicionais em java , Switch Case


A estrutura `switch case` em Java é uma forma de controlar o fluxo de
execução do programa com base no valor de uma expressão. Ela
permite que você execute diferentes blocos de código com base em
diferentes valores possíveis da expressão.

A sintaxe básica da estrutura `switch case` em Java é a seguinte:

switch (expressao) {
case valor1:
// Bloco de código a ser executado se
expressao for igual a valor1
break;
case valor2:
// Bloco de código a ser executado se
expressao for igual a valor2
break;
// ... outros casos possíveis ...
default:
// Bloco de código a ser executado se
nenhum dos casos anteriores for correspondido
24

Aqui está uma breve explicação dos elementos da estrutura `switch


case`:

- `expressao`: É a expressão cujo valor será verificado em cada caso.


Essa expressão deve ser de um tipo primitivo ou de uma classe que
tenha suporte para igualdade (ou seja, implemente o método `equals`).

- `case valor1:`: Cada `case` representa um valor específico que a


expressão pode assumir. Se a expressão tiver o mesmo valor que
`valor1`, o bloco de código associado a esse `case` será executado.

- `break;`: É necessário incluir o comando `break;` ao final de cada bloco


de código para sair do `switch case` após um caso ser correspondido e
executado. Isso evita a execução de outros casos que seguem o caso
correspondido.

- `default:`: O bloco de código dentro do `default` será executado caso


nenhum dos casos anteriores corresponda ao valor da expressão. O
`default` é opcional e pode ser omitido se não for necessário.

Exemplo:

String data = "Domingo";

switch (data) {

case "Domingo":

System.out.println("Domingo");

break;

case "Segunda":
25

System.out.println("Segunda");

break;

case "Terça":

System.out.println("Terça");

break;

case "Quarta":

System.out.println("Quarta");

break;

case "Quinta":

System.out.println("Quinta");

break;

case "Sexta":

System.out.println("Sexta");

break;

case "Sábado":

System.out.println("Sábado");

break;

default:

System.out.println("Data inválida");
26

break;

Esse código em Java utiliza a estrutura `switch case` para verificar o


valor da variável `data` e exibir o dia da semana correspondente ou uma
mensagem de "Data inválida" caso nenhum dos casos seja
correspondido.

Vamos analisar o código passo a passo:

1. `String data = "Domingo";`: Declaração e inicialização da variável


`data` com o valor "Domingo".

2. `switch (data) { ... }`: Início da estrutura `switch case` com a


expressão `data`. O valor de `data` será verificado em cada caso.

3. `case "Domingo":`: O primeiro `case` representa o valor "Domingo".


Se o valor de `data` for igual a "Domingo", o bloco de código associado
a esse `case` será executado.

4. `System.out.println("Domingo");`: Se a expressão `data` for igual a


"Domingo", esta linha imprimirá "Domingo" no console.

5. `break;`: O comando `break;` é necessário para sair do `switch case`


após o caso correspondido ser executado. Sem o `break`, a execução
continuaria para os casos seguintes.

6. Os próximos `case` seguem a mesma lógica. Se `data` tiver o valor


correspondente a um dos dias da semana, o bloco de código associado
será executado.

7. `default:`: O bloco de código dentro do `default` será executado caso


`data` não corresponda a nenhum dos dias da semana especificados
nos `case`.
27

8. `System.out.println("Data inválida");`: Caso `data` não corresponda a


nenhum dos dias da semana especificados nos `case`, esta linha
imprimirá "Data inválida" no console.

9. `break;`: O `break;` no final do `default` também é necessário para


sair do `switch case` após o bloco do `default` ser executado.

Portanto, se `data` tiver o valor "Domingo", o programa imprimirá


"Domingo" no console. Se `data` tiver o valor "Segunda", imprimirá
"Segunda", e assim por diante. Se `data` tiver qualquer outro valor
diferente dos dias da semana especificados, o programa imprimirá
"Data inválida".

Operador Ternário.

Vamos fazer uma analogia divertida entre o operador ternário em Java e


o vilão Duas-Caras (Two-Face) do Batman.

O operador ternário em Java é uma forma compacta de escrever uma


estrutura condicional que envolve três partes: a condição a ser
verificada, o valor a ser retornado se a condição for verdadeira e o valor
a ser retornado se a condição for falsa.

Analogia:
Imagine que o operador ternário é como a personalidade dividida do
vilão Duas-Caras, Harvey Dent, um ex-promotor de Gotham City que,
após um acidente com ácido, desenvolveu uma dupla personalidade.
Uma metade de seu rosto ficou desfigurada e caótica, enquanto a outra
permaneceu intacta e nobre.

1. A condição:
Assim como a personalidade dividida do Duas-Caras, o operador
ternário tem uma "condição" que é verificada. Em Java, essa condição é
uma expressão ou uma avaliação que resulta em um valor booleano
(verdadeiro ou falso). Isso equivale à dualidade do Duas-Caras.
28

2. A primeira opção:
Quando a condição seja verdadeira, o operador ternário retorna o
primeiro valor, que representa a metade do rosto do Duas-Caras que
permaneceu intacta e nobre. É como se a justiça e a integridade
estivessem prevalecendo.

3. A segunda opção:
Quando a condição é falsa, o operador ternário retorna o segundo valor,
que representa a metade do rosto desfigurado e caótico do Duas-Caras.
Essa parte corresponde à corrupção e à maldade.

A estrutura da analogia fica assim:

```
String duasCaras =("Bom" == "Bom") ? "Sim" : "Não";
System.out.println(duasCaras);

Assim como o Duas-Caras tem duas personalidades distintas lutando


por domínio, o operador ternário permite que você tome decisões com
base em uma condição e retorne diferentes valores com base nessa
escolha. É uma ferramenta poderosa e prática para escrever código
conciso e eficiente em Java.

DEBUG:

Em Java, "debug" refere-se ao processo de identificar e corrigir erros


(bugs) em um programa ou aplicação. O debug é uma etapa
fundamental do desenvolvimento de software, pois ajuda os
29

programadores a entenderem como o código está sendo executado e a


encontrar e corrigir problemas que possam surgir durante a execução
do programa.

O processo de debug geralmente envolve o uso de ferramentas de


desenvolvimento, chamadas de depuradores (debuggers), que
permitem aos desenvolvedores pausarem a execução do programa em
pontos específicos, examinar o estado das variáveis e avaliar o fluxo do
programa passo a passo. Com isso, os desenvolvedores podem
identificar onde ocorre o erro e entender melhor a causa raiz do
problema.

Além do uso de depuradores, também são comuns outras técnicas de


debug, como a utilização de logs, impressões (prints) de mensagens
para verificar o estado das variáveis em pontos-chave do código e a
utilização de testes automatizados para detectar problemas. O debug é
uma habilidade essencial para os programadores, pois ajuda a garantir
a qualidade e a confiabilidade do software desenvolvido.

Estruturas de Repetição.

Em Java, existem três principais estruturas de repetição que permitem


executar um bloco de código várias vezes:

1. for: A estrutura "for" é útil quando o número de iterações é conhecido


antes do início do loop.

Exemplo:

for (int i = 0; i < 5; i++) {


System.out.println("Número: " + i);
}
30

2. while: A estrutura "while" executa um bloco de código repetidamente


enquanto uma condição especificada for verdadeira.

Exemplo:

int contador = 0;
while (contador < 5) {
System.out.println("Contador: " + contador);
contador++;
}

3. do-while: Semelhante à estrutura "while", mas a diferença é que o


bloco de código é executado pelo menos uma vez antes de verificar a
condição.

Exemplo:

int i = 0;
do {
System.out.println("Valor: " + i);
i++;
} while (i < 5);

É importante ter cuidado ao usar as estruturas de repetição para evitar


loops infinitos. Certifique-se de que a condição de parada seja
alcançada para evitar que o programa fique preso em um loop infinito.

BitWise.

Em Java, os operadores bit a bit, também conhecidos como operadores


bitwise, permitem manipular os bits individuais de um valor numérico.
31

Os operadores bitwise atuam em nível de bit, o que significa que eles


operam bit a bit em vez de operar em todo o valor.

Existem quatro operadores bitwise principais em Java:

1. AND bitwise ( & ): O operador AND bitwise compara os bits de dois


operandos e produz um resultado com 1 apenas nos bits onde ambos
os operandos têm 1.

2. OR bitwise ( | ): O operador OR bitwise compara os bits de dois


operandos e produz um resultado com 1 em qualquer bit onde pelo
menos um dos operandos tenha 1.

3. XOR bitwise ( ^ ): O operador XOR bitwise compara os bits de dois


operandos e produz um resultado com 1 apenas nos bits onde os
operandos têm valores diferentes (0 e 1 ou 1 e 0).

4. Complemento bitwise ( ~ ): O operador de complemento bitwise


inverte os bits de um único operando, transformando 0 em 1 e 1 em 0.

Exemplo:

int a = 5; // Representado em binário como 0101


int b = 3; // Representado em binário como 0011

int andResult = a & b; // Resultado do AND bitwise:


0001 (1 em decimal)
int orResult = a | b; // Resultado do OR bitwise:
0111 (7 em decimal)
int xorResult = a ^ b; // Resultado do XOR bitwise:
0110 (6 em decimal)
int complementResult = ~a; // Resultado do
complemento bitwise: 1111 1010 (-6 em decimal, devido
ao complemento de 2)

System.out.println("AND: " + andResult);


32

System.out.println("OR: " + orResult);


System.out.println("XOR: " + xorResult);
System.out.println("Complemento: " +
complementResult);

Saída:

```
AND: 1
OR: 7
XOR: 6
Complemento: -6

Os operadores bitwise são úteis quando é necessário manipular valores


em nível de bit, como em casos de configurações de flags, otimizações
de código ou manipulação de dados compactados, recomendo a leitura
do livro matemática é lógica para concurso pois estas operações entre
“bits” é bem semelhante ao uso de tabelas Verdades, e se você for
programar um arduino se vai ter que usar essa parada.

Operações com String.

Em Java, as strings são objetos que representam sequências de


caracteres. A classe `String` possui vários métodos que permitem
realizar diversas operações com strings. Algumas das operações mais
comuns incluem:

1. Concatenação de strings: Para combinar duas strings, você pode


usar o operador `+` ou o método `concat()` da classe `String`.

```java
String str1 = "Olá";
String str2 = "Mundo";
33

String resultado1 = str1 + " " + str2; // Concatenação usando o operador


+
String resultado2 = str1.concat(" ").concat(str2); // Concatenação usando
o método concat()
```

2. Tamanho da string: Para obter o tamanho (número de caracteres) de


uma string, você pode usar o método `length()`.

String texto = "Exemplo";


int tamanho = texto.length();
System.out.println(tamanho);

3. Extrair parte da string: Para extrair um subconjunto de caracteres de


uma string, você pode usar o método `substring()`. Lembre-se que o
índice começa em 0.

String texto2 = "abcdefgh";


String parte = texto2.substring(2, 5);
System.out.println(parte);

4. Comparação de strings: Para comparar duas strings quanto ao


conteúdo, use o método `equals()` ou `equalsIgnoreCase()` (ignora
diferenças de maiúsculas e minúsculas).

String str1 = "Hello";


String str2 = "hello";
boolean saoIguais = str1.equals(str2);
boolean saoIguaisIgnore = str1.equalsIgnoreCase(str2);
System.out.println(saoIguais + " " + saoIguaisIgnore);
34

5. Verificar se uma string contém outra: Para verificar se uma string


contém uma determinada sequência de caracteres, use o método
`contains()`.

String texto3 = "Isso é um exemplo";


boolean contem = texto3.contains("exemplo");
System.out.println(contem);

Essas são apenas algumas das muitas operações que podem ser
realizadas com strings em Java. A classe `String` possui vários outros
métodos úteis para manipular e transformar strings.

Funções em java.

Em Java, funções são chamadas de "métodos". Um método é um bloco


de código que executa uma tarefa específica e pode receber
argumentos, processá-los e retornar um valor, se necessário. Aqui está
um exemplo simples de como um método é definido em Java

import java.util.Scanner;

public class Funcoes {

public static void main(String[] args) {


Scanner sc = new Scanner(System.in);
System.out.println("Enter three numbers : ");
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
int higher = max(a, b, c);
showResult(higher);
35

sc.close();
}

public static int max(int x, int y, int z) {


int aux;
if (x > y && x > z) {
aux = x;
} else if (y > z) {
aux = y;
} else {
aux = z;
}
return aux;
}

public static void showResult(int value) {


System.out.println("Higher = " + value);
}
}

Este programa Java permite que o usuário insira três números e, em


seguida, determina e exibe o maior desses três números utilizando
funções.
segue uma breve explicação sobre cada uma das partes deste código:

1. Importando a classe `Scanner` para leitura de entrada do usuário.


2. A classe `Funcoes` contém o método `main`, que é o ponto de
entrada do programa.
3. O `Scanner sc` é criado para receber entradas do usuário.
4. O programa solicita ao usuário para inserir três números.
36

5. Os números inseridos são lidos usando `sc.nextInt()` e armazenados


nas variáveis `a`, `b` e `c`.
6. O método `max(a, b, c)` é chamado, passando os três números como
argumentos. Esse método verifica qual dos três números é o maior e
retorna esse valor.
7. O resultado retornado pelo método `max` é armazenado na variável
`higher`.
8. O método `showResult(higher)` é chamado para exibir o resultado
(maior número) na tela.
9. O `Scanner` é fechado para liberar recursos.

O método `max` é responsável por comparar os três números e


determinar o maior entre eles, utilizando uma série de condições. O
resultado é então retornado. O método `showResult` apenas imprime o
resultado na tela.

No geral, esse código demonstra como usar funções em Java para


realizar cálculos específicos e modularizar o código, tornando-o mais
organizado e legível.

OOP em Java.

Embora os conceitos de herança, polimorfismo e as leis de Mendel


pertençam a áreas diferentes - programação orientada a objetos e
genética, respectivamente - podemos encontrar algumas analogias ou
paralelos conceituais que podem ajudar a entender a relação entre eles
de forma abstrata. No entanto, é importante notar que essas conexões
não são baseadas em princípios científicos, mas sim em analogias
didáticas para facilitar a compreensão.

1. Herança e Genes:
Na genética, Mendel descobriu que características são transmitidas
através de genes de uma geração para a próxima. Os genes podem ser
vistos como "classes base" que contêm informações hereditárias. Em
um sentido mais abstrato, as características específicas (atributos e
métodos) que uma planta ou animal herda podem ser comparadas aos
37

atributos e métodos que uma subclasse herda de sua classe base na


programação orientada a objetos.

2. Polimorfismo e Variação Genética:


Mendel também observou que as características de organismos eram
variáveis devido à recombinação genética. Isso pode ser comparado ao
polimorfismo na programação orientada a objetos, onde objetos
diferentes, embora compartilhem uma base comum, podem exibir
comportamentos variados. Assim como diferentes combinações de
genes levam a diferentes características, diferentes implementações de
métodos em subclasses levam a diferentes comportamentos
polimórficos.

3. Herança Múltipla e Características Combinadas:


Um exemplo de herança múltipla na genética é quando um organismo
herda características de ambos os pais. Analogamente, em
programação orientada a objetos, você pode usar herança múltipla para
criar uma classe que herda atributos e métodos de várias classes base,
combinando suas características.

4. Seleção Natural e Encapsulamento:


Embora isso seja um pouco mais abstrato, a seleção natural, que está
relacionada à sobrevivência das características mais adaptadas, pode
ser comparada ao conceito de encapsulamento na programação
orientada a objetos. O encapsulamento envolve esconder detalhes
internos de uma classe, permitindo que apenas os aspectos relevantes
sejam acessados externamente. Assim como a seleção natural
"escolhe" características mais vantajosas, o encapsulamento permite
que somente o comportamento necessário seja acessado, tornando o
código mais limpo e seguro.

Em Java, herança e polimorfismo são amplamente utilizados, neste


caso acho viável focar nesses conceitos e vermos como ambos estão
intimamente ligados às leis de Mendel.
38

1. Herança: Em Java, você pode criar classes que herdam atributos e


métodos de uma classe base usando a palavra-chave `extends`. Por
exemplo:

class Animal {
void fazerBarulho() {
System.out.println("Animal faz barulho");
}
}

class Cachorro extends Animal {


@Override
void fazerBarulho() {
System.out.println("Cachorro late");
}
}

2. Polimorfismo: O polimorfismo permite que objetos de classes


diferentes sejam tratados de maneira uniforme. Isso é alcançado
usando a herança e a capacidade de substituir (override) métodos. Por
exemplo:

Animal meuAnimal = new Cachorro();


meuAnimal.fazerBarulho(); // Isso imprimirá "Cachorro late"

Definição de Object.
Toda classe Java é, em essência, uma subclasse de `Object`. Mas o
que é exatamente um objeto? Um `Object` é nada mais do que uma
instância de uma classe. Em outras palavras, um objeto é uma
39

representação concreta de uma classe, composto por seus próprios


atributos (variáveis) e métodos (funções).

Em termos mais simples, uma classe é como um modelo ou um molde


que define a estrutura e o comportamento que um objeto específico
terá. Quando você cria um objeto a partir de uma classe, está criando
uma instância única daquela classe, com seus próprios valores para as
variáveis de instância (atributos) e a capacidade de chamar os métodos
definidos na classe.
Por exemplo, considere uma classe Carro:

package entities;
public class Carro {

public String Marca;


public String Modelo;

public void Ligar() {


System.out.println("Ligando o carro");
}
}

Logo em seguida criamos uma instância desse Objeto Carro na classe Principal:

import entities.Carro;

public class App {


public static void main(String[] args) {
Carro car = new Carro();
car.Marca = "Fiat";
car.Modelo = "Uno";
}
40

No exemplo acima, car é um objeto da classe Carro. Ele possui


suas próprias variáveis marca e modelo, e pode chamar o
método ligar() definido na classe Carro.
Em resumo, um objeto em Java é uma instância específica de
uma classe, que contém seus próprios dados (variáveis de
instância) e comportamentos (métodos).

Membros Estáticos.

Membros estáticos em Java são elementos de uma classe que


pertencem à própria classe em vez de pertencerem a instâncias
individuais dessa classe. Eles são compartilhados por todas as
instâncias da classe e podem ser acessados sem criar uma
instância da classe.

Existem dois tipos principais de membros estáticos em Java:


variáveis estáticas (ou campos estáticos) e métodos estáticos.

1. Variáveis Estáticas (Campos Estáticos): São variáveis


declaradas com a palavra-chave `static`. Essas variáveis
pertencem à classe, não a instâncias individuais. Todas as
instâncias da classe compartilham o mesmo valor para a variável
estática. Elas são geralmente usadas para armazenar valores que
são comuns a todas as instâncias da classe.

public class Exemplo {


static int contador = 0; // Variável estática

public Exemplo() {
contador++; // Incrementa o contador sempre que um novo objeto
é criado
}
}
41

2. Métodos Estáticos: São métodos declarados com a palavra-


chave `static`. Esses métodos pertencem à classe, não a instâncias
individuais. Eles podem ser chamados diretamente através da
classe, sem a necessidade de criar um objeto.
public class Matematica {
public static int soma(int a, int b) {
return a + b;
}
}

Ao usar membros estáticos, você não precisa criar um objeto da


classe para acessar esses elementos. Por exemplo:

int resultado = Matematica.soma(5, 3); // Chamada ao método estático


soma diretamente através da classe

É importante notar que métodos estáticos não podem acessar


membros de instância (variáveis ou métodos não estáticos)
diretamente, pois eles não estão vinculados a uma instância
específica. Variáveis estáticas podem ser acessadas através da
classe, mas também podem ser acessadas através de uma
instância (apesar de não ser a forma mais recomendada).

Orientação a objetos.

1-Constutor
O construtor representa uma operação especial de uma classe que
assume a responsabilidade pela inicialização de um objeto no
instante de sua criação. É viável definir múltiplos construtores em
uma mesma classe, resultando em uma sobrecarga construtiva.
O construtor obriga você programador a fornecer alguns dados no
momento de sua instanciação, vamos a um exemplo:
42

public Product(String name, double price, int quantity) {


this.name = name;
this.price = price;
this.quantity = quantity;
}
Neste exemplo o construtor `public Product(String name, double
price, int quantity)` é um método especial dentro da classe
`Product` que é chamado quando um novo objeto dessa classe é
criado. Ele tem a função de inicializar os atributos do objeto com os
valores fornecidos durante a criação.

Vamos analisar cada parte do construtor:

- `public Product(...)`: Isso declara o construtor público para a


classe `Product`, que pode ser acessado de fora da classe para
criar objetos `Product`.

- `String name, double price, int quantity`: Esses são os parâmetros


que o construtor recebe ao ser chamado. Eles representam os
valores que serão usados para inicializar os atributos do objeto.

- `this.name = name;`: Aqui, `this.name` refere-se ao atributo


`name` da própria instância do objeto `Product` sendo criado. O
sinal de igual (`=`) atribui o valor do parâmetro `name` (recebido
pelo construtor) ao atributo `name` do objeto.

- `this.price = price;`: Semelhante ao exemplo anterior, este trecho


atribui o valor do parâmetro `price` ao atributo `price` do objeto.

- `this.quantity = quantity;`: Novamente, este trecho atribui o valor


do parâmetro `quantity` ao atributo `quantity` do objeto.

Em resumo, quando você cria um novo objeto `Product` e passa os


valores para o construtor `Product(String name, double price, int
quantity)`, esse construtor é responsável por inicializar os atributos
`name`, `price` e `quantity` do objeto com os valores fornecidos.
43

Isso garante que cada objeto `Product` tenha seus atributos


preenchidos corretamente assim que for criado.

Palavra-chave This.

A palavra-chave "this" faz referência direta a um objeto ou valor.


Por exemplo, "this.Produto" faz referência direta ao objeto
"produto". Ela é usada para diferenciar atributos de variáveis locais
e para passar o próprio objeto na chamada de um método ou
construtor, por exemplo:

this.name this.price this.age

name price age

Cada this. está fazendo referência direta a um objeto presente em


cada um dos quadradinhos. De maneira resumida, a palavra-chave
"this" faz referência a um objeto (Variavel). Para um exemplo
adicional, consideremos que você tenha uma lata de Coca-Cola, e
usando o "this", seria "this.coca", referindo-se ao objeto (latinha de
Coca-Cola).

Sobrecarga de métodos
A sobrecarga de método é um conceito em programação que
permite que uma classe tenha vários métodos com o mesmo
nome, mas com diferentes parâmetros. Isso possibilita que
você chame o mesmo método de maneira conveniente,
passando diferentes conjuntos de argumentos, dependendo
das suas necessidades. No código que você forneceu, há um
exemplo de sobrecarga de método na classe `Product`.

Aqui estão os dois construtores da classe `Product`:


44

public Product(String name, double price, int quantity) {


this.name = name;
this.price = price;
this.quantity = quantity;
}
public Product(String name, double price) {
this.name = name;
this.price = price;
}

Observe que ambos os métodos têm o mesmo nome, ou seja,


"Product", mas eles têm diferentes tipos e/ou números de
parâmetros. Isso é o que define a sobrecarga de método.

No primeiro construtor, há três parâmetros: `name`, `price` e


`quantity`. Ele é usado quando você deseja criar um objeto
`Product` com todas as informações disponíveis, incluindo o
nome, preço e quantidade.

No segundo construtor, há apenas dois parâmetros: `name` e


`price`. Isso permite que você crie um objeto `Product` com
nome e preço, mas sem especificar a quantidade. Isso pode
ser útil em situações em que você não tem a quantidade
disponível no momento da criação do objeto.

A sobrecarga de método ajuda a tornar o código mais flexível e


legível, pois você pode escolher o construtor mais apropriado
com base nos dados que possui disponíveis. Em ambos os
casos, a utilização do "this" é importante para diferenciar os
atributos da classe (os atributos `name`, `price` e `quantity`)
dos parâmetros passados para o construtor. Isso permite a
atribuição correta dos valores aos atributos do objeto.

Referência e valor em Java.


45

Em Java, quando você trabalha com variáveis e objetos, é


importante entender a diferença entre passagem por referência e
passagem por valor. Vamos explorar esses conceitos:

1. Passagem por Valor (Tipos Primitivos):


- Quando você passa um tipo primitivo (como `int`, `double`,
`char`, etc.) para um método ou atribui a uma variável, você está
passando o valor real do dado.
- Isso significa que qualquer alteração feita na cópia dentro do
método não afetará a variável original fora do método.
- Exemplo:
public class PassByValueExample {
public static void main(String[] args) {
int x = 10;
changeValue(x);
System.out.println(x); // Output: 10
}

public static void changeValue(int value) {


value = 20;
}
}

2. Passagem por Referência (Objetos):


- Em Java, os objetos são passados por valor, mas o "valor" é, na
verdade, uma referência à localização de memória do objeto.
- Isso significa que, quando você passa um objeto para um
método, você está passando uma cópia da referência ao objeto,
não uma cópia do próprio objeto.
- Portanto, as alterações feitas no objeto dentro do método
afetarão o objeto original fora do método.
- Exemplo:
46

public class Reference {

public static void main(String[] args) {


StringBuilder str = new StringBuilder("Hello");
modifyString(str);
System.out.println(str);
}

public static void modifyString(StringBuilder s) {


s.append(" World");
}
}

Em resumo, Java usa passagem por valor para tipos primitivos e


passagem por valor de referência para objetos. Mesmo que objetos
sejam passados como valores de referência, a linguagem Java não
permite a manipulação direta dos endereços de memória,
proporcionando uma camada de abstração e segurança. Isso pode
levar a uma confusão, mas entender essa diferença é fundamental
para desenvolver aplicativos eficazes e evitar erros sutis.

Vetores em Java.
Em matemática, um vetor é uma entidade geométrica que possui
magnitude (tamanho) e direção. Ele é representado por uma seta
que começa em um ponto e aponta em uma direção específica.
Vetores são usados para representar diversas quantidades físicas,
como deslocamento, velocidade, força, entre outras.

Em programação, como no Java, um vetor (ou array) é uma


coleção de elementos do mesmo tipo, organizados em uma
sequência indexada. Os elementos podem ser acessados por meio
de um índice, que indica a posição do elemento no vetor. Em Java,
os vetores começam a contar do índice 0.
47

Por exemplo, em matemática, um vetor bidimensional (2D) pode


ser representado como:

v=[
x
y
]

Em Java, um vetor (array) de inteiros pode ser declarado da


seguinte forma:

int[] vetor = new int[3]; // Cria um vetor de inteiros com 3 elementos


vetor[0] = 10;
vetor[1] = 20;
vetor[2] = 30;

Portanto, a noção de vetor é semelhante tanto em matemática


quanto em programação, mas os contextos e usos podem variar.
Em matemática, vetores são entidades abstratas que descrevem
direção e magnitude. Em programação, vetores são estruturas de
dados que armazenam uma coleção de valores.
Vetores em Java.
Boxing e unboxing são conceitos em Java relacionados à
conversão entre tipos primitivos e tipos de objeto correspondentes.
Essa conversão é necessária quando você precisa armazenar
valores primitivos em objetos, como coleções, que só podem conter
objetos. Aqui está uma explicação mais detalhada:

1. Boxing:
O boxing envolve converter um tipo primitivo em um objeto
correspondente. Isso é feito automaticamente pelo Java quando
você atribui um valor primitivo a uma variável de um tipo de objeto
correspondente (como `Integer`, `Double`, `Character`, etc.). Por
exemplo:
48

int primitiveValue = 42;


Integer boxedValue = primitiveValue; // Boxing (int to Integer)

2. Unboxing:
O unboxing é a operação oposta do boxing, ou seja, converter
um objeto para um tipo primitivo correspondente. Isso também é
feito automaticamente pelo Java quando você atribui um objeto de
um tipo de objeto correspondente a uma variável de um tipo
primitivo. Por exemplo:

Integer boxedValue = 123;


int unboxedValue = boxedValue; // Unboxing (Integer to int)

É importante mencionar que o Java realiza automaticamente o


boxing e unboxing em muitas situações para facilitar a
programação. No entanto, isso também pode causar algumas
implicações de desempenho em operações frequentes. Por
exemplo, em loops onde ocorrem conversões repetidas, a
performance pode ser afetada negativamente devido à criação de
objetos temporários.
List<Integer> numbers = new ArrayList<>();
numbers.add(5); // Boxing
numbers.add(10); // Boxing

int sum = 0;
for (Integer num : numbers) {
sum += num; // Unboxing in each iteration
}

Em cenários de alta performance, pode ser benéfico evitar


repetidas conversões de boxing e unboxing usando tipos primitivos
sempre que possível, ou utilizar coleções especializadas como
`IntArrayList` de bibliotecas como o Eclipse Collections ou o
`TIntArrayList` do Trove, que evitam a criação de objetos
desnecessários.
49

IntArrayList numbers = new IntArrayList();


numbers.add(5);
numbers.add(10);

int sum = 0;
for (int num : numbers) {
sum += num;
}

No entanto, para muitos casos, o boxing e unboxing automático


fornecido pelo Java é uma conveniência útil e apropriada.

Wrapper classes.
As "wrapper classes" (classes invólucro) em Java são classes que
fornecem uma forma de trabalhar com tipos primitivos como se
fossem objetos. Elas são usadas para converter tipos primitivos em
objetos e fornecer funcionalidades adicionais, como métodos
auxiliares e recursos de tratamento de nulo. Cada tipo primitivo tem
sua própria classe invólucro correspondente. Aqui estão as
principais wrapper classes em Java:

1. `Byte`: Representa um valor numérico de tipo byte.


2.`Short`: Representa um valor numérico de tipo short.
3. `Integer`: Representa um valor numérico de tipo int.
4. `Long`: Representa um valor numérico de tipo long.
5. `Float`: Representa um valor numérico de tipo float.
6. `Double`: Representa um valor numérico de tipo double.
7. `Character`: Representa um caractere Unicode.
8. `Boolean`: Representa um valor booleano (true ou false).

Essas classes fornecem métodos úteis para conversão,


manipulação e comparação dos tipos primitivos. Por exemplo:

// Usando wrapper classes para conversão e manipulação

Integer num = Integer.valueOf("123"); // Converte uma String para


Integer
50

int intValue = num.intValue(); // Converte Integer para int

Double doubleNum = 3.14;


double doubleValue = doubleNum.doubleValue(); // Converte Double para
double

// Comparando valores usando wrapper classes


Boolean result = Boolean.valueOf(true);
if (result.equals(Boolean.TRUE)) {
System.out.println("O resultado é verdadeiro!");
}

Uma das vantagens das wrapper classes é a capacidade de


representar valores nulos usando o conceito de "autoboxing". Isso
significa que você pode atribuir `null` às variáveis das classes
invólucro, permitindo a representação de valores ausentes:

Integer nullableInt = null;


if (nullableInt == null) {
System.out.println("O valor é nulo.");
}

O Java também introduziu a autoboxing e auto-unboxing, que


permitem a conversão automática entre tipos primitivos e suas
classes invólucro correspondentes, tornando o código mais
conciso:
// Autoboxing
Integer value = 42; // int é automaticamente convertido para Integer

// Auto-unboxing
int extractedValue = value; // Integer é automaticamente convertido
para int

As classes invólucro são frequentemente usadas em cenários onde


tipos primitivos precisam ser tratados como objetos, como em
coleções genéricas, onde só é possível armazenar objetos. Elas
também são úteis para trabalhar com APIs que esperam objetos
51

em vez de tipos primitivos, já que o Java trata automaticamente as


conversões.
Laço ForEach.
No trecho de código a seguir temos a demonstração do uso do
laço "for-each" (ou "enhanced for loop" em inglês), que é uma
maneira conveniente de percorrer elementos em uma coleção ou
matriz em Java. Aqui está uma explicação passo a passo do código
que você forneceu:

public class App {

public static void main(String[] args) {


String[] vect = new String[] { "Maria", "Bob", "Alex" };

for (String obte : vect) {


System.out.println(obte);
}
}
}

Aqui está o que cada parte desse código faz:

1. `public class App`: Você está declarando uma classe chamada


`App`.

2. `public static void main(String[] args)`: Este é o método principal


onde o programa começa a ser executado. Ele aceita um
argumento de matriz de strings `args`, que é usado para passar
argumentos da linha de comando para o programa.

3. `String[] vect = new String[] { "Maria", "Bob", "Alex" };`: Você está
declarando e inicializando uma matriz de strings chamada `vect`
com três elementos: "Maria", "Bob" e "Alex".

4. `for (String obte : vect) {`: Aqui, você está usando um laço "for-
each". O laço irá percorrer cada elemento da matriz `vect` e atribuir
temporariamente cada elemento à variável `obte` do tipo `String`.
52

5. `System.out.println(obte);`: Dentro do laço, você está imprimindo


o valor atual da variável `obte`, que é o elemento atual da matriz.

6. `}`: O fechamento do laço `for-each`.

Portanto, o resultado final da execução desse código será a


impressão dos três elementos da matriz, um por um:

``````
Maria
Bob
Alex
`````

O laço "for-each" é uma maneira mais simples e legível de iterar


sobre elementos em uma coleção ou matriz, especialmente quando
você não precisa acompanhar o índice da iteração.

Data e hora no Java


Trabalhar com data e hora é uma parte essencial em muitos sistemas e aplicações Java.
Para te auxiliar nessa tarefa, o Java oferece diversas classes e métodos que facilitam a
manipulação de datas e horários de forma simples e eficiente.

API de Data do Java 8:

A partir do Java 8, a API de datas foi reestruturada e simplificada, tornando-se mais intuitiva
e poderosa. Essa nova API, baseada no JSR 310, fornece um conjunto abrangente de
ferramentas para lidar com datas, horas, fusos horários e intervalos de tempo. Ela reside no
pacote `java.time` e oferece diversas classes para diferentes necessidades:

`LocalDate`: Representa uma data sem hora, como 2024-05-23.


`LocalTime`: Representa uma hora sem data, como 10:15:30.
`LocalDateTime`: Combina data e hora em um único objeto, como 2024-05-23 10:15:30.
`Instant`:Representa um ponto específico no tempo em UTC (Coordinated Universal Time),
como 2024-05-23T17:48:22.781Z.
`ZoneId`: Define um fuso horário específico, como America/Sao_Paulo.
53

`Duration`: Representa um intervalo de tempo entre dois instantes, como 2 horas e 30


minutos.
`Period`: Representa um intervalo de tempo entre duas datas, como 10 dias.
Exemplos:
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;

public class App {


public static void main(String[] args) {
LocalDate d01 = LocalDate.now();
LocalDateTime d02 = LocalDateTime.now();
Instant d03 = Instant.now();
LocalDate d04 = LocalDate.parse("2024-05-23");
LocalDateTime d05 = LocalDateTime.parse("2024-05-23T18:08:25");
Instant d06 = Instant.parse("2024-05-23T18:08:25Z");
ZoneId d07 = ZoneId.systemDefault();
Duration d08 = Duration.ofSeconds(255);
Period d09 = Period.ofMonths(12);

System.out.println("D01\n" + d01);
System.out.println("D02\n" + d02);
System.out.println("D03\n " + d03);
System.out.println("D04\n" + d04);
System.out.println("D05\n" + d05);
System.out.println("D06\n" + d06);
System.out.println("D07\n" + d07);
System.out.println("D08\n" + d08);
System.out.println("D09\n" + d09);
}
}

Vantagens da API de Data do Java 8:

Imutável: As classes de data e hora são imutáveis, o que significa que seus valores não
podem ser modificados após a criação. Isso garante a segurança e confiabilidade do
código.
Tratamento de fuso horário aprimorado: A API fornece ferramentas para lidar com fusos
horários de forma eficiente, evitando problemas relacionados à conversão de horário.
Suporte para diversas tarefas: A API oferece suporte para diversas tarefas comuns, como
formatação de datas e horas, comparação de datas, cálculo de diferenças de tempo e muito
mais.
54

Trabalhando com arquivos em Java.


No Java, temos várias opções para ler, atualizar e deletar arquivos, e uma delas é a classe
`File`, do pacote `java.io`. Esta classe oferece diversas funcionalidades, tais como:

Method Type Description


canRead() Boolean Verifica se o arquivo pode
ser lido.
canWrite() Boolean Verifica se é possível
escrever no arquivo.
createNewFile() Boolean Cria um novo arquivo.

delete() Boolean Deleta o arquivo.

exists() Boolean Verifica se o arquivo existe.

getName() String Retorna o nome do arquivo.

getAbsolutePath() String Retorna o caminho absoluto


do arquivo.
length() String Retorna o tamanho do
arquivo em bytes.
list() String[] Retorna um array de nomes
de arquivos no diretório
mkdir() Boolean Cria um diretório.

Esses métodos permitem manipular arquivos de diversas maneiras, facilitando a realização


de operações comuns no gerenciamento de arquivos.

FileReader E BufferedReader
No Java, as classes `FileReader` e `BufferedReader` são amplamente utilizadas para leitura
de arquivos de texto. Elas fazem parte do pacote `java.io` e podem ser usadas em conjunto
para uma leitura eficiente. Aqui está uma explicação sobre cada uma e como usá-las:

FileReader
A classe `FileReader` é uma classe que permite a leitura de caracteres de um arquivo. Ela é
adequada para ler arquivos de texto simples e pode ser usada diretamente para ler dados
de um arquivo.

BufferedReader
A classe `BufferedReader` é um wrapper que pode ser usado em conjunto com um
`Reader` (como `FileReader`). Ela adiciona funcionalidades adicionais, como a capacidade
55

de ler linhas inteiras de texto de uma só vez, e melhora a eficiência ao armazenar em buffer
as entradas de dados.

Exemplos de Uso

Usando FileReader
O `FileReader` pode ser usado para ler caracteres de um arquivo diretamente. Aqui está um
exemplo básico:

import java.io.FileReader;
import java.io.IOException;

public class FileReaderExample {


public static void main(String[] args) {
try (FileReader fileReader = new FileReader("example.txt")) {
int character;
while ((character = fileReader.read()) != -1) {
System.out.print((char) character);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Usando BufferedReader com FileReader


Para melhorar a eficiência e facilitar a leitura de linhas de texto, podemos usar
`BufferedReader` junto com `FileReader`. Aqui está um exemplo:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {


public static void main(String[] args) {
try (BufferedReader bufferedReader = new BufferedReader(new
FileReader("example.txt"))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
56

- FileReader: é útil para leitura de caracteres individuais, mas não é muito eficiente para
leitura de grandes quantidades de dados.
- BufferedReader: melhora a eficiência da leitura ao usar um buffer e fornece métodos
convenientes como `readLine()` para ler linhas inteiras de texto.

Em resumo, para uma leitura eficiente de arquivos de texto, é recomendável usar


`BufferedReader` em conjunto com `FileReader`, especialmente quando se espera ler
grandes quantidades de dados ou linhas de texto inteiras.

Você também pode gostar