I had some difficulty with the title, wasn't sure how to word it more accurately.
I'm having this issue, I have a several methods which ask the user for 3 Double inputs.
For each input it checks if it's valid (for example if its a positive value), if it's not it throws an IllegalArgumentException. Now I made a Tester class to check if the methods are working properly. It's supposed to catch the exception thrown by the methods and re-ask the user for the input which caused that specific exception.
All 3 methods throw and IllegalArgumentException but the error message is different for each one. Is there anyway (when catching the exception) to see which input cause the error? Here's a sample of my code:
public class account
{
double value;
public account(double initialValue)
{
if (initialValue < 0)
{
throw new IllegalArgumentException("Initial value cannot be negative.");
}
value = initialValue;
}
public add(double addValue)
{
if (addValue < 0)
{
throw new IllegalArgumentException("Added value cannot be negative.");
}
value = value + addValue;
}
}
and the tester class would be something like:
public class accountTester
{
public static void main(String[] args)
{
try
{
double initialValue = Double.parseDouble(JOptionPane.showInputDialog("Enter initial value"));
account acc = new account(initialValue);
double addValue = Double.parseDouble(JOptionPane.showInputDialog("Enter value to add"));
acc.add(addValue);
} catch (Exception e) {
System.out.println("Wrong ammount");
initialValue = Double.parseDouble(JOptionPane.showInputDialog("Re-enter ammount"));
}
}
So what would I have to change in the tester class to throw that code only if the IllegalArgumentException is "Initial value cannot be negative."
Sorry if I made this hard to understand.
EDIT: According to my prof, we're supposed to use do
String error = e.toString;
if (error.contains("Added value cannot be negative.")
{
//DO CODE FOR FIRST ERROR
}
I know this isn't the most proper way of doing it though.
Since you can't match over Strings like you would do in a functional language you have to provide three different kind of objects if you want to be able to distinguish them using the try-catch mechanics.
Or with a simplified approach attach a parameter to the exception so that you can use just a catch clause but you could behave differently. Something like
class MyIllegalArgumentException extends IllegalArgumentException {
public int whichParameter;
public MyIllegalArgumentException(String string, int which) {
super(string);
whichParameter = which;
}
}
now you can:
catch (MyIllegalArgumentException e) {
if (e.whichParameter == 0)
..
else if (e.whichParameter == 1)
..
}
You could also check the string for equality but this would be really not a good design choice, you could also have many try-catch blocks but this is not always possible.
After having expanded your code the solution is easy:
public static void main(String[] args) {
try {
double initialValue = ...
account acc = new account(initialValue);
} catch (IllegalArgumentException e) {
...
}
try {
double addValue = ...
acc.add(addValue);
} catch (Exception e) {
System.out.println("Wrong ammount");
initialValue = Double.parseDouble(JOptionPane.showInputDialog("Re-enter ammount"));
}
}
Surround each method call with its own try/catch block?
In your catch block you should only catch IllegalArgumentException. Then what you can do is invoke the getMessage() function which will enable you to do a very simple String.equals call.
Related
everyone I am a beginner programmer with a little problem on my hands. I am trying to make test statements for one of my classes for a project and have come across a problem. I can't seem to get my try and catch block to work. I have tried using super and inheritance and everything I can think of, but i can;t get it to work. I also can't tell if I'm testing my class or not. I'm so confused on how to set up a try and catch for this class and help would be nice. Thank you so much in advance. Below is my code:
public Resistor (double resistancevalue, double tolerancevalue, double powerrating)throws Exception {
if (resistancevalue <= 0){
throw new Exception ("The resistance value must be greater than zero.");
}
if (tolerancevalue <=0 || tolerancevalue>=1){
throw new Exception ("The tolerance value must be between zero and one (not incusive).");
}
if (powerrating >=0){
throw new Exception("The power rating must be greater than zero.");
}
else{
this.resistancevalue=resistancevalue;
this.tolerancevalue = tolerancevalue;
this.powerrating = powerrating;
}
}
public double getResistanceValue(){
return resistancevalue;
}
double miniResistance(){
double Minir = resistancevalue*(1.0-tolerancevalue);
return Minir;
}
double maxResistance(){
double Maxr= resistancevalue*(1.0+tolerancevalue);
return Maxr;
}
Test class:
public static void main(String[] args) {
// TODO code application logic here
//Tesing the resistor class
//testing to see if the expection is caught when the resistence value is less than 0
double tolerancevalue = 0.5;
double powerrating = 1;
try {
double resistancevalue=1;
System.out.println("Exception Failed");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
You haven't made any actual call to the Resistor constructor. The following code behaves as expected:
try {
double resistancevalue=1;
// the following line will throw an exception...
Resistor r = new Resistor(resistancevalue, tolerancevalue, powerrating);
System.out.println("Exception Failed");
} catch (Exception e) {
// the exception is caught and printed here
System.out.println(e.getMessage());
}
// prints "The power rating must be greater than zero."
You need to call the Resistor constructor inside of the try-catch statement.
public static void main(String[] args) {
// TODO code application logic here
//Tesing the resistor class
//testing to see if the expection is caught when the resistence value is less than 0
double tolerancevalue = 0.5;
double powerrating = 1;
try {
double resistancevalue=1;
Resistor testResistor = new Resistor(resistancevalue,tolerancevalue, powerrating);
System.out.println("Exception Failed");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
Try and catch work if there is an exception in your program (body of try{here}). if there is not an exception they will not work. That is how they work
My code does some arithmetic to convert a binary input to decimal output. I also made an exception class that extends NumberFormatException to throw an error if the input is not a 1 or 0. What I want is to throw the exception to a JTextField.
private void biTodeciActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String binary;
binary = binaryStringText.getText();
int total = 0;
for(int i = 0; i < binary.length(); i++)
{
if (binary.charAt(i) != '0' && binary.charAt(i) != '1')
{
throw new ParseMethods.BinaryNumberFormatException(binary.charAt(i)+" is not"
+" a valid binary input.");
}
else if(binary.charAt(i) == '1'){
total += Math.pow(2, (binary.length()-1)-i );
}
}
deciOut.setText(""+total);
}
Essentially, what you're trying to do won't work. The BinaryNumberFormatException doesn't declare that it throws any exceptions (and assuming you're using NetBeans), you won't be able to (easily) modify it.
You could wrap all you code in a try-catch block within the method, but that's just, well, kind of messy (IMHO)
Instead, what I might do, is create a class which does the conversation, something like...
public static class BinaryConverter {
public static String toDecimal(String binary) throws BinaryNumberFormatException {
//...
}
// Maybe a toBinary method as well...
}
for example. The toDecimal declares the fact that it will throw a BinaryNumberFormatException (although I think some kind of parse exception would be better)
Then in your action performed method, you could do something like...
private void biTodeciActionPerformed(java.awt.event.ActionEvent evt) {
try {
deciOut.setText(BinaryConverter.toDecimal(binaryStringText.getText()));
} catch (BinaryNumberFormatException exp) {
exp.printStackTrace();
deciOut.setText(exp.getMessage());
}
}
which would allow to deal with the operation been successful and unsuccessful in a more succinct manner.
This makes the code more reusable and easier to manager.
As an idea
Print exception directly into textfield in STRING format
deciOut.setText(""+exp);
Ok so I have a method with a switch statement but I left out the rest of the cases because they're not important. In my main method, the operator method is called and passed the parameter "selection" in a while loop until they choose "Q".
When the user enters a negative number, it should throw an exception, print a message, and ignore their input but then loop back to the beginning. When this exception is thrown it terminates the program. Any help would be very much appreciated. Thanks!
public static void operator(String selection) throws IllegalArgumentException{
Scanner input = new Scanner(System.in);
double price;
switch(selection){
case "A":
System.out.println("Enter the price");
if(input.nextDouble()<0){
throw new IllegalArgumentException("Price cannot be a negative value");
}
else{
price = input.nextDouble();
}
break;
case"Q":
System.exit(0);
}
}
An IllegalArgumentException inherits from RuntimeException, for it not to stop your program you can just use a simple try{} catch {} but i don't recommend doing that with Runtime Exceptions. If that's the case, create your own Exception inheriting from java.lang.Exception.
You can use try catch here.
Something like this should work:
public static void operator(String selection) {
Scanner input = new Scanner(System.in);
double price;
switch(selection){
case "A":
System.out.println("Enter the price");
try {
if(input.nextDouble()<0) {
throw new NegativePriceException();
}
} catch (NegativePriceException e) {
System.out.println("The price can't be negative.");
e.printStackTrace();
}
price = input.nextDouble();
break;
case"Q":
System.exit(0);
}
}
And to make your own Exception class you basically need to inherit from Exception (if you want to use try catch on it) or inherit from RuntimeException (if you want it to stop your program from running), like this:
public class NegativePriceException extends Exception {
public NegativePriceException() {
super();
}
}
Java requires that you handle or declare all exceptions. If you are not handling an Exception using a try/catch block then it must be declared in the method's signature.
In your main method you should handle the Exception
public static void main(String args[]) {
//codes
try{
operator("A");
}
catch(IllegalArgumentException e){
e.printStackTrace();
}
}
You've gotten some good answers already on how to handle the exception.
For your case I don't think an exception is appropriate at all. You should get rid of the exception altogether and just handle the problem input by printing an error message and asking for a new input.
Exceptions are for exceptional situations, they should not be part of the normal execution of your code.
I know how to assert that an Exception is thrown. But, how can I assert that an Exception was thrown and it was successfully caught? For example, say I have a method which should throw a particular type of exception for invalid inputs
public static void myMethod(String value) {
try {
someExternalMethod(value);// can throw IllegalArgumentException
} catch (IllegalArgumentException e) {
System.out.println("Let me handle it differently");
} catch (Exception e) {
System.out.println("Not IllegalArgumentException");
}
}
Now I want to assert that for some values the method indeed has thrown 'IllegalArgumentException' and not some other Exception.
In the context of testing myMethod you cannot (and more importantly, you should not want to) check that someExternalMethod has thrown IllegalArgumentException. In fact, your tests of myMethod should not assume that a call of someExternalMethod has been made: it is an implementation detail of myMethod.
The very reason myMethod catches these exceptions is to hide them from its callers. You should check that these exceptions are hidden from you by passing values that cause them, and verifying that nothing is thrown in both cases.
Testing someExternalMethod, along with the exceptions that it throws, is the task accomplished by testing someExternalMethod, not myMethod.
You're missing the important point of unit testing - tests should test behaviour, not implementation.
Given this assumption you should be testing the behaviour of myMethod is as expected when an IllegalArgumentException occurs. It's hard to say any more than that with the method you've shown given the parameter, a single String is immutable, there is no return value and no exceptions are thrown.
A better example might be this method (which is a little contrived to demonstrate the point):
public double divide(int numerator, int denominator)
{
try
{
return numerator / denominator;
}
catch (ArithmeticException e)
{
return Double.NaN;
}
}
Where your tests would assert that the division is correct and that when an error occurs NaN is returned, like this:
#Test
public void testDivide()
{
assertEquals(2.0, divide(4, 2), 0);
}
#Test
public void testDivideByZero()
{
assertTrue(Double.isNaN(divide(1, 0));
}
You could then re-write the divide method like this:
public double divide(int numerator, int denominator)
{
if (denominator == 0)
{
return Double.NaN;
}
else
{
return numerator / denominator;
}
}
And the tests would confirm the operation of my system because the behaviour of the divide method remains unchanged.
catch blocks are evaluated in the order they are.
Your code works fine: in case of IllegalArgumentException, Exception block will be ignored.
Mock method someExternalMethod(value) to force throw Exception
Test method myMethod, checking that is not throwing Exception:
#Test
public void testMyMethod() {
try {
myMethod("value");
} catch (Exception ex) {
Assert.fail();
}
}
Consider this simple program. The program has two files:
File Vehicle.java
class Vehicle {
private int speed = 0;
private int maxSpeed = 100;
public int getSpeed()
{
return speed;
}
public int getMaxSpeed()
{
return maxSpeed;
}
public void speedUp(int increment)
{
if(speed + increment > maxSpeed){
// Throw exception
}else{
speed += increment;
}
}
public void speedDown(int decrement)
{
if(speed - decrement < 0){
// Throw exception
}else{
speed -= decrement;
}
}
}
File HelloWorld.java
public class HelloWorld {
/**
* #param args
*/
public static void main(String[] args) {
Vehicle v1 = new Vehicle();
Vehicle v2 = new Vehicle();
// Do something
// Print something useful, TODO
System.out.println(v1.getSpeed());
}
}
As you can see in the first class, I have added a comment ("// throw exception") where I would like to throw an exception. Do I have to define my own class for exceptions or is there some general exception class in Java I can use?
You could create your own Exception class:
public class InvalidSpeedException extends Exception {
public InvalidSpeedException(String message){
super(message);
}
}
In your code:
throw new InvalidSpeedException("TOO HIGH");
You could use IllegalArgumentException:
public void speedDown(int decrement)
{
if(speed - decrement < 0){
throw new IllegalArgumentException("Final speed can not be less than zero");
}else{
speed -= decrement;
}
}
Well, there are lots of exceptions to throw, but here is how you throw an exception:
throw new IllegalArgumentException("INVALID");
Also, yes, you can create your own custom exceptions.
A note about exceptions. When you throw an exception (like above) and you catch the exception: the String that you supply in the exception can be accessed throw the getMessage() method.
try{
methodThatThrowsException();
}catch(IllegalArgumentException e)
{
e.getMessage();
}
It really depends on what you want to do with that exception after you catch it. If you need to differentiate your exception then you have to create your custom Exception. Otherwise you could just throw new Exception("message goes here");
The simplest way to do it would be something like:
throw new java.lang.Exception();
However, the following lines would be unreachable in your code. So, we have two ways:
Throw a generic exception at the bottom of the method.
Throw a custom exception in case you don't want to do 1.
Java has a large number of built-in exceptions for different scenarios.
In this case, you should throw an IllegalArgumentException, since the problem is that the caller passed a bad parameter.
You can define your own exception class extending java.lang.Exception (that's for a checked exception - these which must be caught), or extending java.lang.RuntimeException - these exceptions does not have to be caught.
The other solution is to review the Java API and finding an appropriate exception describing your situation: in this particular case I think that the best one would be IllegalArgumentException.
It depends. You can throw a more general exception, or a more specific exception. For simpler methods, more general exceptions are enough. If the method is complex, then, throwing a more specific exception will be reliable.