How to create a proper custom exception class? - java

I am trying to create a custom exception class and I'm having a lot of trouble. Can someone help me out! I just started programming very recently and i'm hoping to get some pointers.
import java.util.Random;
import java.util.Scanner;
import java.util.InputMismatchException;
public class GuessingGame {
public static void main(String[]args) throws BadGuessException
{
int min = 1;
int max = 10;
Random rand = new Random();
int numberToGuess = rand.nextInt((max - min) + 1) + min;
Scanner input = new Scanner(System.in);
int guess;
boolean win = false;
int numberOfTries = 0;
while (!win)
{
System.out.println("Guess a number between 1 and 10: ");
try
{
guess = input.nextInt();
numberOfTries++;
if (guess == numberToGuess)
{
win = true;
System.out.println("YOU GOT IT!");
System.out.println("It took you " + numberOfTries + " tires.");
}
else
{
throw new BadGuessException();
}
}
catch(InputMismatchException e)
{
e.getMessage();
}
}
}
}
import java.util.*;
public class BadGuessException extends Exception {
String message = "Sorry, that was an invalid guess!";
//Default Constructor
public BadGuessException()
{
super();
}
//Parameterized Constructor
public BadGuessException(Throwable cause)
{
super(cause);
}
}
I'm supposed to create 2 constructors, one default and one parametrized. If the user enters a number between 1-10, i should catch it in a catch block and print the message "invalid guess" And if they enter a letter or something, the output should be something like "Invalid input" ( Should I catch invalid input in BadGuessException and then pass it to InputMismmatch? If so, how do I do that?)
Right now, when I run this code, if I enter a letter, it doesn't crash, but the while loop iterates continuously and I'm not able to enter anymore inputs. It just keeps repeating "Guess a number between 1-10."
I'm assuming it's because once the try block executes once, it doesn't execute again? How do I fix this? Sorry for any confusion, happy to clarify! any help is much appreciated.
Also, I'm not sure how to catch 2 different exceptions at the same time. One for invalid guess and one for invalid input. :/

Exceptions should be used for handling errors, invalid input, illegal, unusual situations. If not guessing the correct number is an error, that sounds like not being a mind reader is an error. So BadGuessException is misused here.
For a better use case, how about throwing this exception for non-sense input? For example, since the program asks the user to input a number between 1 and 10, inputting -3 or 99 would be clearly an error.
The loop in the middle can be corrected accordingly:
while (!win) {
System.out.println("Guess a number between 1 and 10: ");
try {
guess = input.nextInt();
numberOfTries++;
if (guess == numberToGuess) {
win = true;
System.out.println("YOU GOT IT!");
System.out.println("It took you " + numberOfTries + " tires.");
} else if (guess < 1 || guess > 10) {
throw new BadGuessException();
}
} catch (InputMismatchException e) {
input.nextLine();
}
}
As for creating a custom exception class, you already did that. It's written a bit messy way, cleaning it up (removing unnecessary stuff) it becomes:
public class BadGuessException extends Exception {
private static final String message = "Sorry, that was an invalid guess!";
public BadGuessException() {
super(message);
}
}
UPDATE
I fixed another bug in your code: if you enter non-integer input, a InputMismatchException will be thrown. Repeatedly. Forever.
This is because the input.nextInt() doesn't consume the input if it's not valid. So the invalid input stays there, and input.nextInt() will keep failing, putting your program in an infinite loop.
To fix that, you must consume the bad input somehow, for example by reading the line:
} catch (InputMismatchException e) {
input.nextLine();
}

I think what you want is if they make a guess and it is incorrect, that your loop should run again, right? In that case, you should adjust your loop, as I've shown below. Also, where you are catching the InputMismatchException, you are swallowing the exception without printing it or handling it: This is VERY BAD PRACTICE. I've updated this too for you.
while (!win)
{
System.out.println("Guess a number between 1 and 10: ");
try
{
guess = input.nextInt();
numberOfTries++;
win=true;
if (guess == numberToGuess)
{
win = true;
System.out.println("YOU GOT IT!");
System.out.println("It took you " + numberOfTries + " tires.");
}
else
{
throw new BadGuessException();
}
}
catch(InputMismatchException e)
{
System.out.println("Please input a number betwee 1 and 10!");
}
catch(BadGuessException ex) {
System.out.println("Sorry, you guessed the wrong number!");
}
}

You never catch the BadGuessException so it will be thrown out of the while loop and program will exit. You must catch the exception inside the loop if you want to continue.
I agree with janos comment that this is not a good use of exceptions. Guessing wrong is part of the normal game flow, no?
But doing it for the practice, I'd for example pull all logic inside the loop into a new private method, let it throw this exception, and catch it in the loop. You can catch multiple exceptions in a row like this.
while (!win) {
try {
win = makeGuess();
} catch (InputMismatchException e) {
e.getMessage();
} catch (BadGuessException e) {
System.out.println("Wrong guess");
}
}
private boolean makeGuess() throws BadGuessException, InputMismatchException {
...
}

Related

JavaFX is working but the try-catch-finally code isn't

I just started my lesson about exception handling and I'm unsure of what I did wrong in my code -- what I'm aiming to do is to create a UI that asks the user how many pets they own, and checks if the input is an integer. Can anyone point out what's wrong?
I've already tried using label.setText() for my message, and I've also changed the exception I used (I tried NumberFormat).
Here's the block I used (this is the first time I encountered EH, so I find this topic kind of confusing)
String value = input.getText();
int intval = 0;
intval = Integer.parseInt(value);
try {
if (0 >= intval) {
throw new IllegalArgumentException();
}
else
throw new InputMismatchException();
}
catch(IllegalArgumentException e)
{
String outputMessage = "The number must be an integer no less than 0!";
label1.setText(outputMessage);
}
catch(InputMismatchException i) {
System.out.println("Please enter an integer.");
System.out.println("You entered: " + intval);
}
finally
{
System.out.println("You own " + intval + " pets.");
}
The exceptions I want to include are if the user entered another number type instead of an integer, and if the user entered a negative integer instead of a positive one or 0. My code runs, but the try-catch block doesn't really work.
Looks like there are lot of defects in this code! First of all you shouldn't have taken the input as String if you would have taken the input as integer you could have raised the InputMismatchException by which you could have easily told the user saying "enter only integer value", by taking input as the string you will not be able to do that.
Don't use finally block, because no matter how many exceptions are throw by your code the finally block will get executed. Even if you entered -1 at last(while executing the code) it will show "you have -1 pets:" message, as finally block gets executed not matter what happens!
I refactored the code to make it work the same way
Scanner input = new Scanner(System.in);
boolean exceptionHit = false;
int value = 0;
try {
value = input.nextInt();
if (value <= 0) {
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException e) {
String outputMessage = "The number must be an integer no less than 0!";
label1.setText(outputMessage);
exceptionHit = true;
} catch (InputMismatchException i) {
System.out.println("Please enter an integer.");
exceptionHit = true;
}
if (exceptionHit == false)
System.out.println("You have " + value + " pets");
I have removed finally block so the last message will not be displayed every time! I have added a boolean value instead of it which will be set to true if any exception is hit.

Try Catch Block Not Catching String Input (InputMismatchException)

I am needing to stop the user from entering a string value.
Here is what I've tried so far.
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Random;
public class guessinggame
{
public static void main (String[] args)
{
int randomNumber = new Random().nextInt(10);
System.out.println("My number is " + randomNumber + ". ");
System.out.println("I’m thinking of a number between 0 and 9.");
System.out.println("What is your guess:");
Scanner keyboard = new Scanner(System.in);
int guess = keyboard.nextInt();
guess1(guess);
int input = 0;
try{
input = keyboard.nextInt();
}catch (InputMismatchException e){
int guess = keyboard.nextInt();
System.out.println("Invalid.");
}
if (guess < randomNumber) {
System.out.print("your guess was too low.");
}else if (guess > randomNumber){
System.out.print("your guess was too high.");
}else if (guess == randomNumber){
System.out.print("your guess was correct.");
}
}
}
The error I am receiving is: Duplicate local variable guess preventing program from compiling, however I imagine I am also missing bits from making this program do what I want it to.
It needs to only accept integer values as input between 0-9. Anything else (including strings) should return as invalid.
The compiler is giving you the error because you have declared guess twice:
Once at the beginning with int guess = keyboard.nextInt();
Then in the catch clause with int guess = keyboard.nextInt(); again
Also note that you readInt() several times in your code, meaning that you are trying to get user input several times. You should reference guess in your code instead.
If you are often having trouble with compile errors and such, you may want to use an IDE such as Eclipse.
The main error is that you are re-declaring guess in the catch block.
What you really need to do is loop around if invalid data is input
int guess = -1; // some magic number
while (guess <= -1) { // we do not want negative number
try{
guess = keyboard.nextInt();
}catch (InputMismatchException e){
System.out.println("Invalid - try again.");
continue;
}
if (guess >= 0) {
break;
}
System.out.println("We want between 0 and 9 - try again.");
}
// now we have valid value for guess
Edit
As per new requirements
int guess = -1; // some magic number
try{
guess = keyboard.nextInt();
}catch (InputMismatchException e){
// do not need to do anything
}
if (guess < 0) {
System.out.println("Invalid - will exit.");
System.exit(-1);
}
// now we have valid value for guess
int guess = keyboard.nextInt();
should just be
guess = keyboard.nextInt();

Having an incedibly tough time with a loop

I've copied part of the instructions below, and I can code pretty much every part on its own, but getting the control flow together is giving me massive doubts about my ability.
One of my biggest problems is the int gameChanger. Im supposed to immediately verify if it is a integer or not, and loop back if its not. But then Im also supposed to check to see if thebuser ever types "exit". But the input variable for my scanner instance is an integer... So Im stumped. I can use a try catch to check the missmatchexception once the input is being read in, but that doesnt solve the exit issue nor am I able to come up with solid logic to get the try catch to loop back if it indeed isnt an integer. Im thinking a do while loop but I havent gotten it to work.
Instructions:
You can whether the input is a number before attempting to consume it.
int num;
while (true) {
if (scanner.hasNextInt()) {
num = scanner.nextInt();
break;
} else {
// read whatever is there instead.
String line = scanner.nextLine();
if (line.equals("exit"))
System.exit(0);
System.out.println("Please enter a number");
}
}
System.out.println("Number entered " + num);
This gets the job done. Try it out.
import java.util.Scanner;
public class MyCode
{
public static void main(String[] args)
{
String gameInput = ".";
int gameNumber = 0;
boolean inputLoop = true;
Scanner input = new Scanner(System.in);
while(inputLoop == true)
{
try
{
System.out.print("Please enter a valid game number: ");
gameInput = input.next();
if(gameInput.equals("exit"))
{
System.out.println("Program will now end. Goodbye.");
inputLoop = false;
input.close();
}
gameNumber = Integer.parseInt(gameInput);
if(gameNumber >= 20001 && gameNumber <= 21230)
{
System.out.println("You have inputted a valid game number.");
inputLoop = false;
input.close();
}
}
catch(NumberFormatException e)
{
if(!gameInput.equals("exit"))
{
System.err.println("Invalid game number. Please try again.");
}
}
}
}
}

Java Error Handling - Is this the best way to do this?

I have an error in a console program I'm making, in which I can't seem to handle an error.
If a user enters an incorrect input type (such as an float where an int goes), they are reprimanded, and the program functions (even though the program shuts down, it does it my way):
while(!scanner.hasNextLong()){
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
If a user enters, for example, a zero as a variable that cannot equal zero (due to division of zero), the user is reprimanded, and life still goes on, and the program still functions:
while (b == 0) {
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
System.out.println("Second Integer: ");
b = scanner.nextLong();
}
However, if a user attempts to divide by zero, THEN enters an incorrect input type, the program crashes. What am I doing wrong? I've tried entering a try/catch- while loop as I did in other instances, but it doesn't seem to do the trick:
System.out.println("Second Integer: ");
while(!scanner.hasNextLong()){
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
b = scanner.nextLong();
while (b == 0) {
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
System.out.println("Second Integer: ");
b = scanner.nextLong();
}
Your issue is that your input validation appears to be consecutive. That is, you check for invalid input and then you check for zero values. You probably want to do both every time there is input.
You probably want to check for all error cases in a single loop. Something like:
System.out.println("Second Integer: ");
// a loop wrapping your other validation checks
while(scanner.hasNext()){ // while there is input:
while(!scanner.hasNextLong()){ // check for non-long input
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
b = scanner.nextLong();
while (b == 0) { // check for non-zero input
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
System.out.println("Second Integer: ");
b = scanner.nextLong();
}
}
If you try to perform a division by zero, an java.lang.ArithmeticException is thrown and when you try to read a long and user enters something that can't be parsed, InputMismatchException is thrown (possibly what you call a "crash").
Error is occurring because you are using b = scanner.nextLong(); when user enters 0 without checking if user entered a valid long value.
Here is your code adjusted:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long b = 0;
do {
System.out.println("Second Integer: ");
b = readLong(scanner);
if (b == 0) {
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
}
} while (b == 0);
}
private static long readLong(Scanner scanner) {
if (!scanner.hasNextLong()) {
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
return scanner.nextLong();
}

Comparing User Input To Integer

I'm still in the learning part of Java. I've made a kind of guessing game. It looks like this:
import java.util.Scanner;
import java.util.Random;
public class guessing_game {
static Scanner input = new Scanner(System.in);
static Random generator = new Random();
public static void main(String[] args) {
int number;
number = generator.nextInt(20);
System.out.println("Guess the number!");
game(number);
}
public static void game(int number) {
int inputStorage;
inputStorage = input.nextInt();
if (inputStorage == number) {
System.out.println("You've guessed the right number!");
}
else if (inputStorage != number) {
System.out.println("Wrong number, try again!");
game(number);
}
}
}
Now I have a problem. My little sister and I played this "game". My sister was typing on the numpad. She accidently hit the + button before pressing enter and I got some errors. My question is: How can I let my application print a line which is saying that you can only input numbers and then restarts the game stub again?
One way would be to wrap the input.nextInt() in a try catch statement and catch the exceptions that are thrown by input.nextInt(), InputMismatchException. A good tutorial for try catch statements is here if you aren't sure what I am talking about.
try {
inputStorage = input.nextInt();
} catch (InputMismatchException e){
System.out.println("invalid type");
}
Another way you can do this is:
if(input.hasNextInt()){
inputStorage = input.nextInt();
}else{
System.out.println("invalid type");
}
There is also an error with continuing the game try using a while loop with a break if the number was guessed correctly:
int inputStorage;
boolean notGuessed = true;
while(notGuessed)
{
if(input.hasNextInt()){
inputStorage = input.nextInt();
} else{
System.out.println("invalid type");
}
if (inputStorage == number) {
System.out.println("You've guessed the right number!");
notGuessed = false;
}
else if (inputStorage != number) {
System.out.println("Wrong number, try again!");
}
}
Well this is quite easy. You can accomplish it in various way.
Try this one
public static int checkInt(String strNumber) {
int Number;
try {
Number = Integer.parseInt(strNumber);
} catch (NumberFormatException ex) {
Number = -1;
}
return Number;
}
Or even simpler:
public static int checkInt(String strNumber) {
Number = Integer.parseInt(strNumber, -1);
return Number;
}
The second one is even simpler because you omit a try catch block, that is rather not correctly used in such case. Read about the functions of Integer class.
You can use a try/catch:
boolean b = true;
while (b) {
try {
inputStorage = input.nextInt();
b= false;
} catch (InputMismatchException e) {
System.out.println("Invalid input. Please enter again!");
}
}
Since the error you got was an Exceptiion: InputMismatchException.
You can explicitly handle the exception using the Exception handling mechanism in java.
Read this
Read this
to know how it actually works.
Above suggested answers are exception handling only.

Categories

Resources