exceptions in java - java

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

Related

Why does throwing an unchecked exception removes the "missing return statement" error

I am very new at programming and the problem thus might seem very silly. The below mentioned method has a return type as an int array. When we don't throw any unchecked exception it throws an error which I understand. But why does including an unchecked exception removes that error? It still does not have any return statement, isn't it correct?
public static int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == target - nums[i]) {
return new int[] { i, j };
}
}
}
//throw new IllegalArgumentException("No two sum solution");
}
There is no actual requirement for there to be a return statement in a method with a non-void return type. For example:
int huh() {
while (true) {}
}
is legal.
The requirement is that the method can't complete normally (JLS):
If a method is declared to have a return type (§8.4.5), then a compile-time error occurs if the body of the method can complete normally (§14.1).
Normal completion is basically when execution "falls off the bottom" of the method, that is, reaches the end of the method without encountering a return or throw statement.
So, if you put a throw statement at the end of your method, execution can't reach the end of the method, so it's legal.
In the case of the huh() example above, the while loop doesn't complete normally, so execution cannot reach the end of the method, so you don't need a return or throw there.
There are cases where your program never reaches the inner return statement. E.g. if nums has a length of 0 or if nums[j] == target - nums[i] is never true. For these cases the method needs either return something or it can throw an exception. It is your decision what is the correct behaviour for your use case. If nothing is defined for such cases and your IDE would let you get through with it you would have broken code. If you throw an exception instead of doing nothing your IDE says its fine because your code is correct on a technical level.
The exception forcibly punts you from the called method. The calling method is then forced to catch the exception and continue computation without access to the return value of the called method.
If the exception is unavoidable / unconditional, then a return statement that follows is never necessary or useful.

Exception is never thrown in the corresponding try block

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;
}
}

Correct usage of IllegalArgumentException

Original question is here
I am reading in a UTF-8 file and parsing the contents of that file. If there is error in the file there is no point to continue and execution should stop. I have been suggested to throw IllegalArgumentException if there are problems with the contents, but the API doc says:
Thrown to indicate that a method has been passed an illegal or
inappropriate argument.
In my code, the argument would be the file (or actually the path) that I pass, is it correct to throw IllegalArgumentException in case something goes wrong while parsing? If not, what type of exception should I throw?
private char[][] readMazeFromFile(Path mazeFile) throws IOException {
if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) {
throw new IllegalArgumentException("Cannot locate readable file " + mazeFile);
}
List<String> stringList = Files.readAllLines(mazeFile, StandardCharsets.UTF_8);
char[][] charMaze = new char[stringList.size()][];
for (int i = 0; i < stringList.size(); i++) {
String line = stringList.get(i);
if (line.length() != charMaze.length)
throw new IllegalArgumentException(String.format("Expect the maze to be square, but line %d is not %d characters long", line.length(), charMaze.length));
if (line.contains("B")) {
startX = i;
startY = line.indexOf("B");
}
if (line.contains("F")) {
endX = i;
endY = line.indexOf("F");
}
charMaze[i] = line.toCharArray();
}
if (startX == -1 || startY == -1)
throw new IllegalArgumentException("Could not find starting point (B), aborting.");
if (endX == -1 || endY == -1)
throw new IllegalArgumentException("Could not find ending point (F), aborting.");
return charMaze;
}
I think the first usage is correct:
if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) {
throw new IllegalArgumentException("Cannot locate readable file "+mazeFile);
}
Since (as the documentation states) an invalid file was provided as the argument, this should throw an IllegalArgumentException.
Once you know you have an actual file that meets those requirements, I personally don't think that is a good exception to throw. This will cause other developers to question the type of argument that was given as opposed to the contents of the file. I guess your options are:
Keep it as is, just with very specific error messages explaining
why this was an invalid argument.
Use some other, potentially more applicable java exception such as java.text.ParseException, since it is the file parsing that is causing the error.
Create a custom exception class that more sufficiently describes the issue with the file, e.g. a MazeParseException (per the comments) or a FileFormatException.
I would expect the second or third option to be more beneficial if you anticipate several other developers executing your function.
Exceptions are mainly nothing but names, My best advice here would be to make your own.
Primary reason being that IllegalArgumentExceptions are unchecked exceptions because they extend java.lang.RuntimeException. They would just cause problems if you used them in a context like this.
(Source)
Change the method signature to
private char[][] readMazeFromFile(Path mazeFile) throws IOException, MazeParseException {...}
And all throw new IllegalArgumentException with throw new MazeParseException
(except for the first usage as per #Joel's answer)
The MazeParseException.java file:
package yourPackage.here;
import java.lang.Exception;
public class MazeParseException {
public MazeParseException() {
super();
}
public MazeParseException(String reason) {
super(reason);
}
}
The benefits here of using your own exception is that you can tag extra data along with the exception relating to your situation, for example you could add:
private int errorLineNum = null;
public MazeParseException(String reason, int lineNum) {
this(reason);
this.errorLineNum = lineNum;
}
public int getMalformedLine() {
return this.errorLineNum;
}
// And then update the toString() method to incorperate the errorLineNum
#Override
public String toString() {
StringBuilder sb = new StringBuilder(super.toString());
if(errorLineNum != null) {
sb.append("# line #");
sb.append(this.errorLineNum);
}
return sb.toString();
}
As JSON or XML library send their own execption if the file doesn't match what they are looking for (a JSON file or a XML one), I think you should do the same if doesn't match what you are looking for( an UTF-8 file ).
IllegalArgumentException should be use for internal problem in your code and should not be throw when your code have been debug. Also you should not catch an IllegalArgumentException and you will probably want to catch it in your program.

Can we make the JVM to throw our own user defined exception?

In java predefined Exceptions throws automatically. like,
int a=10, b=0;
c = a/b;
throws ArithmeticException
int a[3] = {1, 2, 3};
int b = a[4];
throws ArrayOutOfBoundException
wherein in case of user-defined exceptions we should create an object of that Exception class and throw it manually.Can I make my own Exception to behave like the above two cases?
Can I make my own Exception to behave like the above two cases?
No, it would have to be built into the JVM.
You may, but you have to catch the original and then throw your own.
try {
int a=10, b=0;
int c=a/b;
catch (Exception e){
//disregard exception, throw your own
throw new MyCustomException("My Custom Message");
}
Or, if you have a condition where you want to throw an exception on a case where an exception wouldn't normally exist, you just throw it!
// In this case, only move forward if a < b
int a = 10, b = 0;
if (a >= b)
throw new MustBeLessThanException("a must be less than b!");
Or something silly like that.
Be sure to make the custom class extend Exception or one of the subclasses.
No, all you can do is catch and then throw your own:
try {
int a=10, b=0;
c = a/b;
} catch (ArithmetikException e) {
throw MyException("Bad!", e); // pass in e to getr a meaningful stacktrace
}
But I really wouldn't recommend that (except in cases where you have to, ie. when implementing an interface that doesn't declare an exception that might be thrown in your code). But then again, your example both are RuntimeExceptions (which are unchecked) and those don't have to be declared.

How can I throw a general exception in Java?

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.

Categories

Resources