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.
Related
I have this method:
public int addInt(int x, int y){
try{
if(x<1 || y<1){
throw new InvalidValueExeption();
}
} catch(InvalidValueExeption i){
System.out.println(i);
}
return x+y;
}
InvalidValueExeption is a custom exception. So I wanted to test this:
#Test
public void test(){
AddClass a = new AddClass();
boolean thrown = false;
try{
a.addInt(-2, 3);
} catch(InvalidValueException e){
thrown=true;
}
assertTrue(thrown);
}
I can't run this test, because it says Exception exception.InvalidValueException is never thrown in the corresponding try block.
What am I doing wrong?
Your addInt() method doesn't throw InvalidValueException (*). Inside the method, you do throw it, but you catch it before it can "leave" your method. So, for the outside world, there is no InvalidValueException coming from your method.
Then, correctly the compiler tells you that there's no point in catching the InvalidValueException.
So, instead of immediately catching the exception inside your method, declare the method to throw InvalidValueException:
public int addInt(int x, int y) throws InvalidValueException {
if (x < 1 || y < 1) {
throw new InvalidValueException();
}
return x + y;
}
Rationale:
Exceptions are meant to tell the caller (**) of some method that it couldn't fulfill its task, i.e. your addInt() method is designed to add only positive numbers. And if someone tries it with a number below 1, the method answers with the exception instead of returning a value, thus saying: "Hey, something went wrong, so I can't give you an answer (and the problem description is [the exception with its message and so on])."
( * ) I assume, the missing "c" is just a typo, and you don't have two different exception classes.
( ** ) That's important. I'm not talking about System.out.println(), as that's telling something to the user, not the caller.
If InvalidValueExeption is a checked exception then the compiler will complain because addInt is not declared to throw InvalidValueExeption.
If InvalidValueExeption is not a checked exception then the test will fail because addInt swallows the InvalidValueExeption.
There's also a possible typo in your question: addInt() throws InvalidValueExeption whereas test() tries to catch InvalidValueException. In the former case exception is spelled "Exeption", in the latter case it is spelled "Exception", note the missing "c".
The following approach will work:
public int addInt(int x, int y) {
if (x < 1 || y < 1) {
throw new InvalidValueException();
}
return x + y;
}
#Test(expected = InvalidValueException.class)
public void test(){
AddClass a = new AddClass();
a.addInt(-2, 3);
}
First of i think your InvalidValueExeption is a subtype of RuntimeException.
RuntimeException and its subclasses are unchecked exceptions.
Unchecked exceptions do not need to be declared in a method or
constructor's throws clause if they can be thrown by the execution of
the method or constructor and propagate outside the method or
constructor boundary.
So if you need to indicate that you throw an InvalidValueExeption or inherit Exception instead.
Here the exception is declared on your method and thrown :
public int addInt(int x, int y) throws InvalidValueExeption {
try {
//..
throw new InvalidValueExeption();
} catch (InvalidValueExeption e) {
// do some logging the throw back at you
throw e;
}
}
i m writing a very simple java class and i faced a weird problem, i know there are many simple way to resolve it but now i have a doubt
public class Frazione {
private int num;
private int den;
public Frazione(int x, int y) throws FrazioneException {
if (y == 0) {
throw new FrazioneException();
}
num = x;
den = y;
}
/*public Frazione(int x){ THAT'S HOW IT SHOULD BE BASED
ON THE EXCERCISE BUT IT WON'T
COMPILE BECAUSE THIS ISN'T THE
FIRST STATEMENT
try{
this(x,1);
}catch(FrazioneException e){
System.err.print("errore: "+e);
}
}*/
/*public Frazione(int x){
this(x,1); IF I TRY THIS WAY I'LL BE IN
AN UNREPORTED EXCEPTION PROBLEM
}*/
public int getNum() {
return num;
}
public int getDen() {
return den;
}
}
there's a way to use try and catch with this() statement?
Yes, this doesn't work. You'd have to fulfill two contradictory requirements:
the this call has to be the first statement
the this call has to be in a try..catch statement.
So this can't be solved.
What you could do:
If you want to throw a checked exception in the constructor, throw it also in the other one. But that doesn't make real sense, because it will never been thrown, because you never pass y=0
Convert FrazioneException to a runtime exception and remove throws.
Try to solve your requirement without throwing an exception from the constructor (I usually avoid that because it often causes too much trouble. Like the one you have)
If there are multiple constructors and you are using this keyword within a constructor to call another constructor, the invocation of another constructor (this()) must be the first line of the constructor.
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();
}
}
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.
I wrote a code which checks all kinds of conditions.
If it meets the condition it does what it is supposed to, otherwise I want it to throw an
exception.
Is there any special syntax for that? Otherwise the compiler wants me to return any array,
which I don't want to, due to the pre-condition.
Here is part of my code:
public static int [] code(int[]arr){
if ((arr!=null)&&(chack4and5(arr))&&(arr[arr.length-1]!=4)&&(TwoFours(arr))){
int k=0;
for(int i = 0; i<=arr.length-1; i++){
if (arr[i] == 4){
int place= pos(arr,k);
arr[place]=arr[i+1];
arr[i+1]=5;
k=k+3;
}
}
return arr;
}
else {
System.out.println("Please enter a legal array which matches the pre- conditions");
}
}
}
The way to throw an exception is
throw new IllegalArgumentException(
"Please enter a legal array which matches the pre- conditions");
IllegalArgumentException is a Java runtime exception suitable for the current situation, but of course you can choose another one, or create and use your own type too. The only restriction is that it must be a subclass of java.lang.Exception.
I would rearrrange your code though to check the preconditions first, then proceed if everything's fine - I find this more readable:
if (arr == null || !chack4and5(arr) || arr[arr.length-1] == 4 || !TwoFours(arr)) {
throw new IllegalArgumentException(
"Please enter a legal array which matches the pre- conditions");
}
int k=0;
for(int i = 0; i<=arr.length-1; i++){
if (arr[i] == 4){
int place= pos(arr,k);
arr[place]=arr[i+1];
arr[i+1]=5;
k=k+3;
}
}
return arr;
(In fact, I would even prefer extracting the precondition check into a separate method - but I leave this to you.)
throw new IllegalArgumentException(
"Please enter a legal array which matches the pre- conditions")
java.langIllegalArgumentException is a RuntimeException that means some of the arguments are not as they are expected to be. Since it is an unchecked exceptions, your callers are not forced to handle it in any way (as opposed to checked exceptions)
You can throw an Exception by yourself. Maybe the best way to do this is defining a custom exception and then throwing it. If you don't want to do that use an IllegalArgumentException.
Here an example of a custom exception:
public static int [] code(int[]arr) {
if ((arr!=null)&&(chack4and5(arr))&&(arr[arr.length-1]!=4)&&(TwoFours(arr))){
int k=0;
for(int i = 0; i<=arr.length-1; i++){
if (arr[i] == 4){
int place= pos(arr,k);
arr[place]=arr[i+1];
arr[i+1]=5;
k=k+3;
}
}
return arr;
}
else {
throw new MyException("No legal array");
}
}
}
And here your custom exception:
public class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
If the exception is that something about your arguments is illegal, then throw an IllegalArgumentException:
throw new IllegalArgumentException("descriptive message")
You may want to take a look at Oracle's tutorials on exceptions.
To throw an exception, you use the throw keyword.
To mark that a method may throw an exception, use the throws keyword, like
public static void foo() throws SomeException
You can throw exception with this line
throw new SomeKindOfException("Exception description"); // or any other exception, also yours...
But you need to specify at the method declaration:
public static int [] code(int[]arr) throws SomeKindOfException{
See Oracle tutorial for more