Try Catch

Turco

Buenas, he empezado este año a estudiar DAM, y se nos ha mandado un proyecto para la 1º evaluación.

El proyecto en cuestión es un programita el cual te muestre la teoría de un tema, puedas responder a 10 preguntas que previamente han sido seleccionadas aleatoriamente y en base al tiempo que hayas tardado, te lo muestre y además te de una calificación, la última parte es lo mismo que la anterior, pero que además de mostrar las preguntas, también muestre las respuestas.

Ya lo tengo casi finiquitado, a excepción de por un error que me da en el menú. El caso es que tengo declarada una variable de tipo entero para las opciones del menú, por lo que si el usuario ingresa algo que no sea de tipo entera, peta dando como error:

Exception in thread "main" java.util.InputMismatchException

public static void menu() {

		boolean repetir = true;
		int opcion;
		
		do {
		System.out.print(menu);
		opcion = teclado.nextInt();
		teclado.nextLine();
		System.out.println("\n");
		
		if (opcion == 1)
			System.out.print(teoria);
		else 
			if (opcion == 2) {
				actividad();
			} else
				if(opcion == 3)
					actividadresuelta();	
				else
					if(opcion == 4){
				System.out.println("Adiós");
				repetir = false;
					} else
						if(opcion < 1 || opcion > 4)
             System.out.println("Error número incorrecto");
			
		} while (repetir);
	}

Ese es el código del menú. He probado haciendo un vector de tipo String en el que guardaba los valores {"1", "2", "3", "4"} de manera que solucionaba el error, ya que ahora fuera lo que fuera lo que el usuario ingresara, podía controlarlo.

Haciendo esto, el programa no funciona del todo bien, ya que en el momento en el que estando en las actividades, si el usuario responde de manera incorrecta, me tira al menú en vez de continuar haciendo las preguntas (sólo puede salir apretando el 0 o terminando las 10 preguntas).

Así que la cuestión por la que posteo es... ¿como puedo hacer un try catch para capturar ese error y devolver una String que diga que el valor ha de estar entre 1-4?.

package Proyecto;

import java.util.Scanner;

public class Try {
    public static void main(String arg[]) {
    	
	Scanner teclado = new Scanner(System.in);
	int opcion;
	opcion = teclado.nextInt();
    
    try
    {
        if (opcion != 1 || opcion !=2 || opcion !=3 || opcion !=4);
        	
    }
    catch(java.util.InputMismatchException excepcion)
    {
         System.out.println("El valor debe estar entre 1-4");
    }
    teclado.close();
}
}

Eso es lo que he probado hasta ahora, pero no funciona.

Amazon

El problema que tienes es que te está petando el programa fuera del try/catch, es decir, en el momento en el que asignas a una variable de un tipo un contenido de otro D:

1 respuesta
Turco

#2 Agradezco la respuesta, pero en lo que al try/catch se refiere, soy noob total, apenas vimos algo en clase, y lo estoy utilizando además de para conseguir algún puntillo extra, para solventar el hecho de que no pueda hacerlo con String.

¿Como podría solucionarlo?. ¿Tendría que hacerlo en la clase donde tengo el menú o en el try/catch?. Estoy un pelín perdido xD

1 respuesta
LLoid

#3

Lo que Amazon te quiere decir es que tienes el try catch mal colocado. La excepción salta cuando metes algo que no es un número en

opcion = teclado.nextInt();
teclado.nextLine();

por lo que es ahí donde tienes que poner el try catch:

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

	boolean repetir = true;
	int opcion = 0;

	do {
		try {
			Scanner teclado = new Scanner(System.in);
			opcion = teclado.nextInt();
			teclado.nextLine();
		} catch (java.util.InputMismatchException excepcion) {
			System.out.println("Introduce un número entre 1 y 4");
		}
		System.out.println("\n");

		if (opcion == 1) {
			System.out.println("1");
		} else if (opcion == 2) {
			System.out.println("1");
		} else if (opcion == 3) {
			System.out.println("1");
		} else if (opcion == 4) {
			System.out.println("Adiós");
			repetir = false;
		} else if (opcion < 1 || opcion > 4)
			System.out.println("Error número incorrecto");
	} while (repetir);
}
}
1 respuesta
FrioneL

Dentro de un try { } catch añades el codigo que crees que puede crashear para que el catch gestione el problema en caso de darse.

Btw, no creo que sea buena solucion añadir try catchs en tu codigo. Si sabes que en una parte del codigo puede petar, asegurate de añadir las condiciones necesarias para que no lo haga.

A lo del input del user, en java hay cosas como "StringUtils.isNumericSpace" que te dice si dado un string, es numerico. Añade un if mas que en caso de no ser numerico, no haga nada, o algo asi.

2 respuestas
Amazon

#4 No quería darle las cosas hechas :(

Pero básicamente #5 . Si sabes que va a petar y además sabes por qué, lo mejor sería que no lo metas directamente en la variable sino que proporcionaras el código adecuado para evitar que pete. Si aún así peta, pues oye, no le puedes hacer más.

Aunque entiendo tu punto de vista y yo también metía en mi época try/catch para que el profesor viera que sabía usarlo y me subiera un poco la nota D:

Turco

Al final me funcionó lo del try/catch, pero en vez de devolverme la sentenca que le ponía en el catch, me devolvía además de eso, la misma pregunta repetida dos veces xD.

Investigando para ver si en vez de hacerlo con una variable de tipo entero, podía hacerlo con una de tipo String, me puse a investigar por el código y resulta que era una variable booleana que fuera del todo, que se me estaba sobreescribiendo con la del menú xD.

Pues eso, que me tendrán de vez en cuando pidiendo ayuda por aquí :P. Gracias a todos.

sasher

#5 ¿Por que no es buena idea usar un try-catch en este caso? No es una aplicación en tiempo real cuya dependencia del rendimiento deba ser óptima. Justo para este tipo de errores usar excepciones es más que adecuado.

1 respuesta
FrioneL

#8 Porque no son buenas practicas y para alguien que esta aprendiendo, mejor que no los use y se centre en arreglar los problemas que puedan ocurrir, en vez de poner try catchs en todo el codigo hasta que no pete.

1 respuesta
Seyriuu

Soy de la opinión de que los try catchs, cuantos menos, mejor.

Ahora bien, al profesor de #1 lo que le interesa es ver que ha aplicado los últimos conocimientos dados en clase, que por lo que dice entiendo que fue el Try catch. Así que yo lo pondría para que lo viera el profesor.

De hacerlo sin try, lo que haría es capturar como un string, y si el string es 1,2,3 o 4 pasarlo a integer para usarlo en el menú, caso contrario daría un mensaje por print y daría de nuevo comienzo con el menú.

sasher

#9 Mucho mejor llenar todo el código de condicionales como si estuviéramos programando en C. Me gustaría una fuente de un libro o algo donde diga que capturar excepciones son "malas prácticas".

Ronso

Viendo eso siempre me entra la misma duda... Es mejor usar if-else o hacer un switch? Perdon por el offtopic.

2 respuestas
eXtreM3

#12 switch es más rápido en la mayoría de casos.

1
B

#12 yo soy partidario de switch cuando tienes muchas condiciones(o casos). If/else/else if en caso de pocos.

1
gonya707

aunque fuese solo por un poco de decoro y de legibilidad de código, switch mejor que if-else de calle

sasher

Además de que un switch en ese caso ahorraría las dos condiciones de comprobación de error con un "default". Pero vamos, como decís, yo también lo haría por legibilidad.

Turco

Al final lo he expuesto hoy y ha ido todo bien ^. Lo del switch estaba pendiente de hacerlo, de hecho, en el código tenía un comentario al respecto xD, pero entre otras asignaturas, se me ha echado el tempo encima y lo he dejado como está.

Al final el menú me quedó así aplicándole una variable de tipo String, con lo que solucioné el problema de si el usuario introducía letras.

public static void menu() {

		boolean repetir = true;
		String opcion = "";

		do {
			
		System.out.print(menu);
		opcion = teclado.nextLine();
		System.out.println("\n");
		
		if (opcion.equals("1"))
			System.out.print(teoria);
		else 
			if (opcion.equals("2")) {
				actividad();
			} else
				if(opcion.equals("3"))
					actividadresuelta();	
				else
					if(opcion.equals("4")){
				System.out.println("Adiós");
				repetir = false;
					} else
						if(!opcion.equals("1") || !opcion.equals("2") || !opcion.equals("3") || !opcion.equals("4"))
							System.out.println("Las opciones válidas son de 1-4");
			
		} while (repetir);
	}

Usuarios habituales

  • Turco
  • sasher
  • Ronso
  • Seyriuu
  • FrioneL
  • Amazon
  • LLoid