Creating an exception class and using it in code - java

Okay, Now that I've updated my code it looks like this:
public static double getDouble (String userShape, String parameter) throws BadShapeData
{
String missingValue = parameter, value = "", shape = userShape;
String s2 = "Enter a value for " + missingValue;
value = JOptionPane.showInputDialog(s2);
if (null == value || value.length() == 0) {
throw new BadShapeData("Error, nothing was entered. Must be double.");
}
try {
return Double.parseDouble(value);
}
catch (NumberFormatException e) {
throw new BadShapeData("Error entering " + value + ". Must be double.");
}
}
And this is also in my code :
public static void main(String args[]) {
int choice;
do {
choice = menu();
if(choice != 0) {
System.out.println(makeShape(choice));
}
} while (choice != 0);
}
public static Shape3D makeShape(int choice) {
if(choice == 1)
return new Cone(getDouble("Cone", "Radius"), getDouble("Cone", "Height"));
else if(choice == 2)
return new Cylinder(getDouble("Cylinder", "Radius"), getDouble("Cylinder", "Height"));
else if(choice == 3)
return new Sphere(getDouble("Sphere", "Radius"));
else if(choice == 4)
return new Box(getDouble("Box", "Length"), getDouble("Box", "Width"), getDouble("Box", "Height"));
else if(choice == 5) return new Pyramid(getDouble("Pyramid", "Base"), getDouble("Pyramid", "Height"));
else return new Cube(getDouble("Cube", "Size"));
}
However now the error I'm getting says "Error: unreported exception BadShapeData; must be caught or declared to be thrown" and is being highlighted where I use the getDouble method

I would remove the return statement that is inside your finally, to outside. I'm not 100% on this, but I think it might be swallowing the exception.

And what value are you passing? notice that if you pass a float, an int, a long, etc. It will correctly parse as a double, because all those types are assignment-compatible with a double. If you want to see the exception being thrown, then pass a different type altogether, for example the string "xyz".
Be aware that a char is a number, so it's possible to assign it to a double variable. For example, this line will not result in a compilation or execution error; it's perfectly valid, albeit potentially confusing:
double c = 'x';
UPDATE:
Try changing your code like this:
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
throw new BadShapeData(value);
}
Of course, you must add throws BadShapeData to the method declaration, like this:
public static double getDouble (String userShape, String parameter) throws BadShapeData
Also you must be aware that from this point onwards, all the parts in the code that call the getDouble() method will have to handle the exception - by catching it or letting it pass through. This is how Exceptions work in Java, as you should know by now.

Either place all calls to getDouble in a full or individual try/catch block(s):
public static void main(String args[]) {
int choice;
do {
choice = menu();
if(choice != 0) {
System.out.println(makeShape(choice));
}
} while (choice != 0);
}
public static Shape3D makeShape(int choice) {
try {
if(choice == 1)
return new Cone(getDouble("Cone", "Radius"), getDouble("Cone", "Height"));
else if(choice == 2)
return new Cylinder(getDouble("Cylinder", "Radius"), getDouble("Cylinder", "Height"));
else if(choice == 3)
return new Sphere(getDouble("Sphere", "Radius"));
else if(choice == 4)
return new Box(getDouble("Box", "Length"), getDouble("Box", "Width"), getDouble("Box", "Height"));
else if(choice == 5) return new Pyramid(getDouble("Pyramid", "Base"), getDouble("Pyramid", "Height"));
else return new Cube(getDouble("Cube", "Size"));
} catch (BadShapeData e) {
System.out.println(e.getMessage());
//do whatever with exception
}
}
OR have makeShape throw the exception then use a try/catch block in void main():
public static void main(String args[]) {
int choice;
do {
choice = menu();
if(choice != 0) {
try {
System.out.println(makeShape(choice));
} catch (BadShapeData e) {
System.out.println(e.getMessage());
//do whatever with exception
}
}
} while (choice != 0);
}
public static Shape3D makeShape(int choice) throws BadShapeData {
if(choice == 1)
return new Cone(getDouble("Cone", "Radius"), getDouble("Cone", "Height"));
else if(choice == 2)
return new Cylinder(getDouble("Cylinder", "Radius"), getDouble("Cylinder", "Height"));
else if(choice == 3)
return new Sphere(getDouble("Sphere", "Radius"));
else if(choice == 4)
return new Box(getDouble("Box", "Length"), getDouble("Box", "Width"), getDouble("Box", "Height"));
else if(choice == 5) return new Pyramid(getDouble("Pyramid", "Base"), getDouble("Pyramid", "Height"));
else return new Cube(getDouble("Cube", "Size"));
}
Which method you choose to implement depends on your needs. Go with first if void main need not know of the BadShapeData exception. Go with second if void main should know and do something about it.

Try this, then:
public static double getDouble (String userShape, String parameter) {
String prompt = "Enter a value for " + parameter;
String value = JOptionPane.showInputDialog(prompt);
if (null == value || value.length() == 0) {
throw new BadShapeData("Error, nothing was entered. Must be double.");
}
try {
return Double.parseDouble(value);
}
catch (NumberFormatException e) {
throw new BadShapeData("Error entering " + str + ". Must be double.");
}
}
public class BadShapeData extends RuntimeException {
public BadShapeData(String message) {
super(message);
}
}

The problem you have is that you hide the exception in finally block;
The finaly block is executed after you throw an exception. This mean it never go out as in finally you return
You should avoid to use return key word in finall block.

Remove return statement in finally block. You just swallow your exception. Instead of this put return outside finally.
Refer related question: Exception is swallowed by finally
UPDATE:
Catch your BadShapeData as it is a checked exception. Another way, which I prefer, to use RuntimeException as base class. It's more flexible, though less safe.

Related

Java : How to check if a method throws a exception and terminate when it does?

class Exceptions {
public String checkExceptions(double n1, double n2, char op) throws DivideByZeroException, MultiplyByZeroException{
try {
if(op == '/' && n2==0) {
throw new DivideByZeroException();
}
else if(op=='*' && (n1==0 || n2==0)) {
throw new MultiplyByZeroException();
}
else {
return "No exception found";
}
}
catch (DivideByZeroException ex) {
return "Division by zero results in infinity";
}
catch(MultiplyByZeroException ex) {
return "Multiplying by zero";
}
catch(Exception ex) {
return op+" not a valid operator";
}
}
public double calculate(double v1, double v2, char op) throws Exception{ //Error: This method must return a result of type double
try{
checkExceptions(v1, v2, op); //This might be wrong place to put the method. Don't know how to check if this method throws an exception or not.
if(op=='+') {
return v1+v2;
}
else if(op=='-') {
return v1-v2;
}
else{
return 0.0;
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
class DivideByZeroException extends Exception{
DivideByZeroException(){
super();
}
}
class MultiplyByZeroException extends Exception{
MultiplyByZeroException(){
super();
}
}
The main method takes the input (2 numbers and an operator('+' or '-' or '/' or '*' only) and passes it to the calculate method. The calculate method should check for an exception and if there is no exception, return the calculated value to the main function i.e. v1+v2 or v1-v2;
Else if an exception exists then it should print the error statement and the value that is returned from the calculate method to the main method should be 0.0(Not printed).
You can try in below way and should work fine. You can even overide Exception constructor to pass error message from exception and print e.getMessage() at place where exception is caught. I have just given you working code with simple message print.
class Exceptions {
public void checkExceptions(double n1, double n2, char op) throws DivideByZeroException, MultiplyByZeroException {
if (op == '/' && n2 == 0) {
throw new DivideByZeroException();
} else if (op == '*' && (n1 == 0 || n2 == 0)) {
throw new MultiplyByZeroException();
}
}
public double calculate(double v1, double v2, char op) throws Exception {
double result = 0.0;
try {
checkExceptions(v1, v2, op);
switch(op){
case '+' : result = v1 + v2;
break;
case '-' : result = v1 - v2;
break;
case '/' : result = v1 / v2;
break;
case '*' : result = v1 * v2;
break;
}
} catch (DivideByZeroException ex) {
System.out.println("Division by zero results in infinity");
} catch (MultiplyByZeroException ex) {
System.out.println("Multiplying by zero");
} catch (Exception ex) {
System.out.println(op + " not a valid operator");
}
return result;
}
}
class DivideByZeroException extends Exception {
DivideByZeroException() {
super();
}
}
class MultiplyByZeroException extends Exception {
MultiplyByZeroException() {
super();
}
}
You can do something like
class Exceptions {
public String checkExceptions(double n1, double n2, char op) throws DivideByZeroException, MultiplyByZeroException {
if (op == '/' && n2 == 0) {
throw new DivideByZeroException("Division by zero results in infinity");
} else if (op == '*' && (n1 == 0 || n2 == 0)) {
throw new MultiplyByZeroException("Multiplying by zero");
} else {
return "No exception found";
}
}
public double calculate(double v1, double v2, char op) {
double result = 0;
try {
System.out.println(checkExceptions(v1, v2, op));// Print the message
if (op == '+') {
result = v1 + v2;
} else if (op == '-') {
result = v1 - v2;
} else if (op == '/') {
result = v1 / v2;
} else if (op == '*') {
result = v1 * v2;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return result;// Return result
}
}
class DivideByZeroException extends Exception {
DivideByZeroException(String message) {// Parametrise it
super(message);// Pass the parameter to the constructor of super class
}
}
class MultiplyByZeroException extends Exception {
MultiplyByZeroException(String message) {// Parametrise it
super(message);// Pass the parameter to the constructor of super class
}
}
public class Main {
public static void main(String[] args) {
Exceptions e = new Exceptions();
System.out.println(e.calculate(10, 0, '/'));
System.out.println(e.calculate(10, 5, '/'));
System.out.println(e.calculate(10, 5, '*'));
System.out.println(e.calculate(10, 0, '*'));
System.out.println(e.calculate(10, 5, '+'));
System.out.println(e.calculate(10, 5, '-'));
}
}
I have written enough comments in the code so that you can understand it easily.
Output:
Division by zero results in infinity
0.0
No exception found
2.0
No exception found
50.0
Multiplying by zero
0.0
No exception found
15.0
No exception found
5.0
UPD: I made mistake you should use
Arrays.asList(Arrays.stream(Operators.values()).map(en -> en.op)).contains(op)
instead
Arrays.asList(Operators.values()).contains(op)
You can use Exception(String message) constructor for your excaptions. Also I think you should use Enum for indicate operators
class Exceptions {
public enum Operators {
PLUS('+'),
SUB('-'),
DIV('/'),
MUL('*');
public final char op;
Operators(char op) {
this.op = op;
}
}
public void checkExceptions(double n1, double n2, char op) throws Exception {
if (op == Operators.DIV.op && n2 == 0) {
throw new DivideByZeroException("Division by zero!");
} else if (op == Operators.MUL.op && (n1 == 0 || n2 == 0)) {
throw new MultiplyByZeroException("Multiplying by zero!");
} else if(Arrays.asList(Arrays.stream(Operators.values()).map(en -> en.op)).contains(op)) {
throw new Exception(op + " not a valid operator!");
}
}
public double calculate(double v1, double v2, char op) {
try {
checkExceptions(v1, v2, op);
if (op == Operators.PLUS.op) {
return v1 + v2;
} else if (op == Operators.SUB.op) {
return v1 - v2;
} else if (op == Operators.MUL.op){
return v1 * v2;
} else if(op == Operators.DIV.op) {
return v1 / v2;
} else {
return 0.0;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return 0.0;
}
}
class DivideByZeroException extends Exception {
DivideByZeroException(String message) {
super(message);
}
}
class MultiplyByZeroException extends Exception {
MultiplyByZeroException(String message) {
super(message);
}
}
}

How to catch a NumberFormatException?

I'm trying to figure out how to catch a numberformat exception error within my code such that if the user inputs a letter within a string and my program tries to parse it to an int my program won't throw up an error but instead stop and return a Boolean value. I'm also trying to understand that if the try statement works I'd like it to continue to execute the following code.
if (counter == 3) {
int compare;
boolean check = true;
String[] newip = IpAddress.split("\\.");
if (newip.length == 4) {
for (int index = 0; index < newip.length; index++) {
//There should be a try statement here.
// if the try statement fails then I'd like for it to catch
// the numberformatexception and evaluate my boolean to
//false;
//but if it passes I'd like for it to continue to execute
//the following code.
compare = Integer.parseInt(newip[index]);
if (compare >= 0 & (compare <= 255)) {
check = true;
}
else{
check = false;
}
}
if (check)
return true;
else
return false;
}
else {
check = false;
return check;
}
}
else{
return false;
}
}
Surround that line with try/catch:
try {
compare = Integer.parseInt(newip[index]);
} catch (NumberFormatException e) {
check = false;
}
and then:
if (check) {
if (compare >= 0 & (compare <= 255)) {
check = true;
} else {
check = false;
}
} else {
return false;
}
Instead of catching NumberFormatException, you can use NumberUtils from commons-lang 3.x to check if the input is a number.
NumberUtils.isNumber(newip[index])
However as per the documentation, it would be deprecated in 4.x and you would need to use isCreatable
NumberUtils.isCreatable(newip[index])

junit.framework.AssertionFailedError - Incomplete Stack Trace Given

Full Disclosure: This was an assignment, it has been marked already, but I want to understand why I'm getting this error.
I'm having some issues understanding why junit.framework.AssertionFailedError is being thrown. Normally when errors occur I could at least look at the stack trace and see what is happening. In this case, the output console shows this:
Testcase: testIsCorrectMCQ(mr_3.myTester): FAILED
null
junit.framework.AssertionFailedError
at mr_3.MyTester.testIsCorrectMCQ(Assign03Tester.java:207)
testIsCorrectMCQ(mr_3.MyTester): FAILED
In the test result tab in NetBeans, copying the stack trace gives me:
junit.framework.AssertionFailedError
at mr_3.myTester.testIsCorrectMCQ(myTester.java:207)
In the tester file, I have this:
#Test
public void testIsCorrectMCQ() {
System.out.println("isCorrect of MCQ");
MCQuestion instance = new MCQuestion(1,"Capital city of Canada is", 'A',
"Ottawa", "Vancouver", "New York", "Toronto");
assertFalse(instance.isCorrect("B"));
assertTrue(instance.isCorrect("A")); // line 207
}
My isCorrect method is this:
#Override
public boolean isCorrect(Object guess) {
if (guess == null)
return false;
if (guess instanceof String) {
String userGuess = (String)guess;
return (userGuess.charAt(0) == this.getAnswer());
}
if (guess instanceof Character) {
Character userGuess = (Character)guess;
return (userGuess == this.getAnswer());
}
else return false;
}
Any help in understanding what is happening is greatly appreciated.
Edit 1 : My MCQuestion source code
public class MCQuestion extends Question {
private char answer;
private String[] options;
public MCQuestion() {
super();
questionType = QuestionType.MULTIPLE_CHOICE;
}
public MCQuestion(int id, String text, char answer, String... options) {
super(id, text);
setOptions(options);
setAnswer(answer);
questionType = QuestionType.MULTIPLE_CHOICE;
}
public String[] getOptions() {
String[] getOptions = new String[this.options.length];
System.arraycopy(this.options, 0, getOptions, 0, this.options.length);
return getOptions;
}
public void setOptions(String... options) {
if (options.length > 0) {
this.options = new String[options.length];
for (int i = 0; i < options.length; i++) {
if (options[i].isEmpty())
throw new IllegalArgumentException("You have nothing in this option");
else
this.options[i] = options[i];
}
}
else throw new IllegalArgumentException("You have no options set");
}
public char getAnswer() {
return this.answer;
}
public void setAnswer(char ans) {
ans = Character.toLowerCase(ans);
int index = ans - 97;
if (Character.isLetter(ans) && index >= 0 && index < this.options.length)
this.answer = ans;
else throw new IllegalArgumentException(ans + " is not a valid answer option");
}
#Override
public boolean isCorrect(Object guess) {
if (guess == null)
return false;
if (guess instanceof String) {
String userGuess = (String)guess;
return (userGuess.charAt(0) == this.getAnswer());
}
if (guess instanceof Character) {
Character userGuess = (Character)guess;
return (userGuess == this.getAnswer());
}
else return false;
}
#Override
public String toString() {
String option = "";
if (this.options.length == 0)
option = "No options added, yet!";
else {
char index = 'a';
for (String e: options)
option += index + ") " + e + "\n";
}
return (super.toString() + "\n" + option);
}
}
You execute ans = Character.toLowerCase(ans); for whatever reason in your setAnswer() method before saving it in this.answer. This means that (userGuess.charAt(0) == this.getAnswer()) will return false when you provide the answer in upper case, but compare it with the stored lower case character.
Depending on if you want case insensitive answers or not, you should add or remove the Character.toLowerCase() call to your isCorrect() method as well.

Probably a very simply answerable query about throwing an exception

This should be easily and quickly answerable. It is about throwing exceptions, and I have very little understanding of that topic (because I am a novice).
The code below represents of the most important methods from my simple 'maze game' program. In this method, I am (obviously) enumerating the possible user keyboard commands and giving the instructions for their execution by calling other sub-methods. Evidently, I want all keyboard inputs that aren't "help", "status" ... "down" to result in the error message at the bottom of the method.
I know that what I've got here is dumb and makes no sense, but that's because I literally have no idea what I'm doing when it comes to throwing exceptions, and I am too lazy to do any serious reading. So I would love if someone could just tell me how to write what I want to write here.
public static void performAction(String action) throws IllegalArgumentException {
if (action.equalsIgnoreCase("help")) {
printHelp(); }
else if (action.equalsIgnoreCase("status")) {
printStatus(); }
else if (action.equalsIgnoreCase("board")) {
printBoard(); }
else if (((action.charAt(0) == 'S') || (action.charAt(0) == 's')) && ((action.charAt(1) == 'a') || (action.charAt(1) == 'A')) && ((action.charAt(2) == 'v') || (action.charAt(2) == 'V')) &&
((action.charAt(3) == 'e') || (action.charAt(3) == 'E')) && (action.charAt(4) == ' ')) {
String [] parts = action.split(" ");
String saveCommand = parts[0];
String fileName = parts[1];
try { saveGame(fileName); }
catch(IOException e) {
System.err.printf("Error: Could not save the current game configuration to \'%s\'.", fileName);
return; } }
else if (action.equalsIgnoreCase("left")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo((a - 1), b); }
else if (action.equalsIgnoreCase("right")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo((a + 1), b); }
else if (action.equalsIgnoreCase("up")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo(a, (b - 1)); }
else if (action.equalsIgnoreCase("down")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo(a, (b + 1)); }
else {
try {}
catch (IllegalArgumentException e) {
System.err.printf("Error: Could not find command \'%s\'.\nTo find the list of valid commands, please type 'help'. \n", action); }
}
}
else {
System.err.printf("Error: Could not find command \'%s\'.\nTo find the list of valid commands, please type 'help'. \n", action);
throw IllegalArgumentException ;
}
This will log the message and then exit the method by throwing IllegalArgumentException exception

Java-Finding whether given numbe is prime or not by using recursive method call

I had done a lot of googling about it but unable to figure out the right answer. While I am running the below code i am always getting output as "not prime even though the input is prime number like 13".
Please help me out.
import java.util.Scanner;
public class PrimeRecurssion {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
System.out.println("Your given number is:" + prime(number,2));
}
public static String prime(int x,int temp )
{
if(x%temp == 0)
{
return("not a prime");
}
if(x != temp-1)
{
return prime(x,temp+1);
}
else
return("prime");
}
}
try
if(x - 1 != temp)
{
return prime(x,temp+1);
}
or
if(x != temp + 1)
{
return prime(x,temp+1);
}
at the moment you compare x with temp - 1
eg. x = 13, temp = 12 what leads to 13 != 12-1
=> so prime(13, 13) is called, which returns with "no prime"
Try to change
if(x != temp-1)
to
if(x != temp+1)
It will not cure all bugs you have, but probably fix it a bit.
public static String prime(int x,int temp )
{
if(x == 1)
{
return "prime";
}
if(x != temp)
{
if(x%temp == 0)
{
return("not a prime");
}
else
{
return prime(x,temp+1);
}
}
else
return("prime");
}
This works because you only want to return prime if you have reached the number itself otherwise you will hit a not prime before that point. Look at the code and see if you can figure out what is going on.

Categories

Resources