Ajuda com condicional e Scanner

Queria saber como eu faço uma condicional para o scanner, esse é o código:

    package com.learn.java;

import java.util.Scanner;

public class main {
  public static void main(String... args) {
    double nota;
    
    Scanner scanNota = new Scanner(System.in);
    
    System.out.println("Informe sua nota:");
       
    nota = scanNota.nextDouble();
    
    System.out.println("Sua nota é: " + nota);
  }
}

Como faço pra colocar uma mensagem caso o usuário não digite um valor Double?

public static void main(String[] args) throws Exception {
	try (Scanner scanNota = new Scanner(System.in)) {
		System.out.println("Informe sua nota:");
		double nota = scanNota.nextDouble();
		
		System.out.println("Sua nota é: " + nota);
	} catch(InputMismatchException ex) {
		System.out.println("A nota informada não é valida");
	}
}

Usei alguns recursos para melhorar o código, caso não conheça sinta-se a vontade para tirar dúvidas.

Não conhecia o Try e Catch, mas veja se estou certo:

Try vai fazer a execução correta, mas se caso houver uma falha na digitação do usuário ao invés de gerar um erro e quebra da execução, o programa de acordo com a Exception no catch, ele faz uma determinada função.

Certo?

@edit

Como faço pra assim que ele der a mensagem de valor inválido volte para o Scanner normal?

@edit
Pra que aquele “throws Exception”?

Isso mesmo. Você pode fazer uma tratativa para contornar a exceção lançada no try.

Você terá que criar um controle que irá repetir a ação. Isso pode ser feito com um laço (ex.: do … while) ou com recursividade.

Quando escrevo exemplos para ajudar a galera aqui, eu sempre uso uma classe que mantenho num projeto de teste e acabei esquecendo de tirar o “throws”.

O throws serve quando vc precisa “subir” (subir é uma forma de retornar a exceção) a exceção lançada para quem chamou o método (nesse exemplo que mandei, ele deve ser ignorado, pois o tratamento já está sendo feito no próprio método…

Valeu mano.

Meu código ficou assim:

import java.util.InputMismatchException;
import java.util.Scanner;

public class NotasEnem {
    public static void main(String[] args) throws InputMismatchException {
        float pNat = 0, pMat = 0, pHum = 0, pLin = 0, pRed = 0;
        float nNat = 0, nMat = 0, nHum = 0, nLin = 0, nRed = 0;
        // PESO NATUREZA
        try {
            Scanner pScanNat = new Scanner(System.in);
            System.out.println("Digite o peso de Natureza:");
            pNat = pScanNat.nextFloat();
        } catch (InputMismatchException ex) {
            System.out.println("Peso inválido.");
        }
        //PESO MATEMATICA
        try {
            Scanner pScanMat = new Scanner(System.in);
            System.out.println("Digite o peso de Matemática:");
            pMat = pScanMat.nextFloat();
        } catch (InputMismatchException ex) {
            System.out.println("Peso inválido.");
        }
        // PESO HUMANAS
        try {
            Scanner pScanHum = new Scanner(System.in);
            System.out.println("Digite o peso de Humanas:");
            pHum = pScanHum.nextFloat();
        } catch (InputMismatchException ex) {
            System.out.println("Peso inválido.");
        }
        // PESO LINGUAGENS
        try {
            Scanner pScanLin = new Scanner(System.in);
            System.out.println("Digite o peso de Linguagens:");
            pLin = pScanLin.nextFloat();
        } catch (InputMismatchException ex) {
            System.out.println("Peso inválido.");
        }
        // PESO REDAÇÃO
        try {
            Scanner pScanRed = new Scanner(System.in);
            System.out.println("Digite o peso de Redação:");
            pRed = pScanRed.nextFloat();
        } catch (InputMismatchException ex) {
            System.out.println("Peso inválido.");
        }
        float pSoma = pNat + pMat + pHum + pLin + pRed;
        if (pSoma == 10) {
            //SISTEMA DE NOTAS

            //NOTA NATUREZA
            try {
                Scanner nScanNat = new Scanner(System.in);
                System.out.println("Digite a nota de Natureza: ");
                nNat = nScanNat.nextFloat();
            } catch (InputMismatchException ex) {
                System.out.println("Peso inválido.");
            }
            // NOTA MATEMATICA
            try {
                Scanner nScanMat = new Scanner(System.in);
                System.out.println("Digite a nota de Matematica: ");
                nMat = nScanMat.nextFloat();
            } catch (InputMismatchException ex) {
                System.out.println("Peso inválido.");
            }
            // NOTA HUMANAS
            try {
                Scanner nScanHum = new Scanner(System.in);
                System.out.println("Digite a nota de Humanas: ");
                nHum = nScanHum.nextFloat();
            } catch (InputMismatchException ex) {
                System.out.println("Peso inválido.");
            }
            // NOTA LINGUAGENS
            try {
                Scanner nScanLin = new Scanner(System.in);
                System.out.println("Digite a nota de Linguagens: ");
                nLin = nScanLin.nextFloat();
            } catch (InputMismatchException ex) {
                System.out.println("Peso inválido.");
            }
            // NOTA REDACAO
            try {
                Scanner nScanRed = new Scanner(System.in);
                System.out.println("Digite a nota de Redacao: ");
                nRed = nScanRed.nextFloat();
            } catch (InputMismatchException ex) {
                System.out.println("Peso inválido.");
            }
            float nSoma = (nNat * pNat) + (nMat * pMat) + (nHum * pHum) + (nLin * pLin) + (nRed * pRed);
            float notaFinal = nSoma / pSoma;
            System.out.println("Sua nota final é: " + notaFinal);
        } else {
            System.out.println("Pesos inválidos.");
        }
    }
}

Obrigado pela ajuda. Se poder fazer o exemplo de retornar só no primeiro peso, fico grato.

Pra que implementar tudo dentro do método main?
O método main deveria ser apenas o ponto de entrada da execução de sua aplicação, é uma má prática implementar tudo dentro dele.

Pra que instanciar tantos Scanner com o System.in?
O System.in é único, então basta ter um único Scanner encapsulando ele.

Percebeu que você tem bastante código repetido nas leituras de pesos e notas?
Pode simplificar criando um método para a leitura.

Veja um exemplo de como seu código poderia ser reescrito:

import java.io.PrintStream;
import java.util.InputMismatchException;
import java.util.Scanner;

public class NotasEnem {

    public static void main(String[] args) throws InputMismatchException {
        NotasEnem programa = new NotasEnem();
        programa.executar();
    }

    private final Scanner entrada = new Scanner(System.in);
    private final PrintStream saida = System.out;

    public void executar() {
        float pNat = lerPeso("Natureza");
        float pMat = lerPeso("Matemática");
        float pHum = lerPeso("Humanas");
        float pLin = lerPeso("Linguagens");
        float pRed = lerPeso("Redação");

        float pSoma = pNat + pMat + pHum + pLin + pRed;

        if (pSoma != 10) {
            saida.println("Pesos inválidos.");
            return;
        }

        float nNat = lerNota("Natureza");
        float nMat = lerNota("Matemática");
        float nHum = lerNota("Humanas");
        float nLin = lerNota("Linguagens");
        float nRed = lerNota("Redação");

        float nSoma = (nNat * pNat) + (nMat * pMat) + (nHum * pHum) + (nLin * pLin) + (nRed * pRed);

        float notaFinal = nSoma / pSoma;
        saida.println("Sua nota final é: " + notaFinal);
    }

    private float lerPeso(String disciplina) {
        while (true) {
            try {
                saida.println("Digite o peso de " + disciplina + ":");
                return entrada.nextFloat();
            } catch (InputMismatchException ex) {
                saida.println("Peso inválido.");
            }
        }
    }

    private float lerNota(String disciplina) {
        while (true) {
            try {
                saida.println("Digite a nota de " + disciplina + ":");
                return entrada.nextFloat();
            } catch (InputMismatchException ex) {
                saida.println("Nota inválida.");
            }
        }
    }
}
1 curtida

Meu Deus kkkkk, sou iniciante, se poder explicar o que você fez, agradeceria muito.

Qual sua dúvida?

Basicamente, 80%.
Estou começando agora. No meu curso a última aula foi de Controle de Fluxo.

Mas dando uma lida nesse seu código, eu entendi a lógica, mas saber usar eu não vou saber kkkk

Tipo, eu vi que você usou 3 classes diferentes, mas como eu sei o que vai acontecer kkkk não consigo entender a relação de classes. Qualquer coisas a mais depois eu pergunto.

Não, criei uma classe chamada NotasEnem e utilizei as classes Scanner, System e PrintStream.
O atributo estático out da classe System é um objeto do tipo PrintStream, só joguei pra uma variável de instância pra não ficar chamando System.out toda hora.

A principal diferença é que não implementei tudo dentro do método main.

No método main eu crio um objeto do tipo NotasEnem e chamo o método executar.

O método executar utiliza dois métodos para ler os pesos e as notas de cada disciplina e implementa a lógica para calcular a média.

1 curtida

Entendi! Muito obrigado. Vou tentar diminuir meus códigos com essa técnica. Só tenho uma dúvida

Como funciona essa questão de eu dizer que a variável pNat seria igual ao lerPeso?
Tipo, como o lerPeso resulta no valor digitado?

Outra kkkk, qual a diferença do public e private?

Está fazendo curso de que exatamente?

Os membros (atributos e métodos) de uma classe possuem um modificador de acesso que determina sua acessibilidade.

public           acessível para qualquer classe em qualquer pacote
protected        acessível para classes dentro do mesmo pacote e para subclasses, mesmo que estejam em outro pacote
sem modificador  acessível somente para classes e subclasses dentro do mesmo pacote
private          acessível somente dentro da classe que o declara

Quando você declara um método você utiliza a seguinte sintaxe:

<modificador-de-acesso> <tipo-de-retorno> <nome-do-método>(<lista-de-parâmetros>) {
    <corpo-do-método>
}

Por exemplo, no método executar temos:

modificador de acesso:    public    significa que qualquer classe em qualquer pacote pode chamar este método
tipo de retorno:          void      significa que este método não retorna nenhum valor para quem o chamar
nome do método:           executar
lista de parâmetros:      vazia     significa que este método não recebe parâmetros

Já no método lerPeso temos:

float lerPeso(String disciplina) {

modificador de acesso:    private   significa que este método só pode ser chamado de dentro da própria classe
tipo de retorno:          float     significa que este método retorna um valor do tipo float para quem o chamar
nome do método:           lerPeso
lista de parâmetros:      somente um parâmetro do tipo String, correspondente ao nome da disciplina da qual se deseja ler o peso

O tipo de retorno do método lerPeso é float, isto significa que este método vai devolver um float para quem o chamar.
O retorno do valor é realizado pela instrução return, na seguinte linha:

return entrada.nextFloat(); // retorna o valor lido pelo nextFloat

Poderia ter escrito o retorno dessa forma, caso pareça mais legível:

float peso =  entrada.nextFloat(); // atribui o valor lido pelo nextFloat a uma variável
return peso; // retorna a variável
1 curtida

Curso de Java.

Obrigado, entendi perfeitamente o que você fez. Muito obrigado.