I'm having some trouble understanding the implications of the code in my accessor method below. Eclipse's compiler is requiring that I have a return statement after my try-catch block. Does this mean that my getter method will always return null or will it return the item I'm trying to retrieve if it int i doesn't need to be caught by the IndexOutOfBoundsException?
public T get(int i)
{
try
{
return bag[i];
}
catch(IndexOutOfBoundsException e) //if(logiSize < i+1)
{
System.out.println("Collection has fewer items than the index you entered!");
System.out.println("Returning null"); //or should I...?
}
return null;
}
Can anyone help me understand the implications here? Thanks so much!
Your method will return bag[i] unless you have an IndexOutOfBoundsException exception executing the return statement. In that case, they exception is caught, and since you're not throwing another exception inside the catch black. The method will proceed to return null.
If you only need to check for bounds, you could do this:
public T get(int i, T[] bag) {
if(i < bag.length) {
return bag[i];
}
return null;
}
Related
I am working on a method. It returns int.
int top() {
return q.peek();
}
The method above works fine for non-empty queue. It is not for empty queue.
When I modify this code to handle empty queue, it will be like this
int top() {
if (q.isEmpty()) {
System.out.println("queue is empty"); // I want to end the process here
return -1; // I don't want this line to return -1
}
return q.peek(); // I don't want this line to execute
}
System.out.println(q.top());
The result will be like this if the queue is empty
queue is empty
-1
I want it to print only queue is empty, not -1.
So is there a way to modify only top() method for this case in Java?
If you are able to change System.out.println(q.top()); to a call to only q.top(); you can simply just print from inside the method:
int top() {
if (q.isEmpty()) {
System.out.println("queue is empty");
return -1;
}
System.out.println(q.peek());
return q.peek();
}
If you are unable to change ANYTHING about the System.out.println(q.top()) statement you would need to return a String instead and use Integer.toString to convert the value to a String:
String top() {
if (q.isEmpty()) {
return "queue is empty";
}
return Integer.toString(q.peek());
}
Are you wanting to print the int returned only if the queue is not empty, otherwise print "queue is empty"? If so, how about doing something like this:
int top() {
if (q.isEmpty()) {
return -1;
}
return q.peek();
}
System.out.println(q.top() == -1 ? "queue is empty" : q.top());
And another option:
int top() throws Exception {
if (q.isEmpty()) {
throw new Exception("queue is empty");
}
return q.peek();
}
try {
System.out.println(q.top());
} catch (Exception e) {
System.out.println(e.getMessage());
}
When a method signature return int, you should not try to return another type as it can confuse other members who read your code.
If you cannot modify the System.out.println() method, the best option is to throw an Exception in your method like the answer given by Caitlyn Wiley.
Another acceptable way is to return an int that signify error (like you did with -1), as long as you have good docs to explain it.
I've just found another way to solve this problem without changing top() data type.
int top() {
if (q.isEmpty())
System.out.println("queue is empty");
System.exit(0);
return q.peek();
}
What do you guys think?
I thank you every answer to my question. I am very grateful.
All answers are very useful.
I have the following method where I wan to keep checking if a nested exception matches an IndexOutOfBoundsException unless the nested exception is the same as the previous one.
It seems to do the right thing where in my test, the first exception
is of type NullPointerException thus moving on to the next. The next exception is as expected, an IndexOutOfBoundsException.
When this happens I want to return true which I expect to break me out of the loop.
It seems to be happening as expected where I do land on 'return true'. But after that, the loop keeps going.
What am I missing. How is it keeping on going even after returning true?
public boolean test(Throwable throwable) {
do {
if(throwable instanceof IndexOutOfBoundsException) {
return true; // I do land here thus expecting to get out of loop and this method.
}
this.test(throwable.getCause());
} while (throwable.getCause() != throwable);
return false;
}
The test against it simulating nested exception.
#Test
void testWithNestedException() {
NullPointerException nullPointerException = new NullPointerException();
IndexOutOfBoundsException indexOutOfBoundsException = new IndexOutOfBoundsException();
Throwable nestedException = nullPointerException.initCause(indexOutOfBoundsException);
assertTrue(someClass.test(nestedException));
}
You are mixing recursion with looping. Here, a simple loop that updates the exception being tested should do the trick:
public boolean test(Throwable throwable) {
Throwable t = throwable;
do {
if (throwable instanceof IndexOutOfBoundsException) {
return true;
}
t = t.getCause();
} while (t.getCause() != t);
return false;
}
You are creating recursion with this call and don't use the return code from this call.
this.test(throwable.getCause());
I think you wanted to do:
throwable = throwable.getCause();
As #Mureinik points out, you are mixing recursion and iteration and doing neither correctly. A (correct) recursive version would be:
public boolean test(Throwable throwable) {
if (throwable == null) {
return false;
} else if (throwable instanceof IndexOutOfBoundsException) {
return true;
} else {
return test(throwable.getCause());
}
}
In my opinion, a recursive version is easier to understand than an iterative one, but others may disagree.
With the recursive version, there is the theoretical problem that sufficiently deeply nested exceptions could lead to a stack overflow. Getting that to happen in practice would require some rather contrived (i.e. unrealistic) code, so it should be safe to ignore this.
I would truly appreciate if someone could help me to understand why my code won't work the way it should:
I'd like to catch the exception when the index being tested (in the main class) is out of bound from my ArrayList in the getter method.
It should behave like: if the index (testing using 8) is out of bound from the ArrayList (length of 5), then the program will not get any value and print out statement saying Will Skip, and keep moving to the next line. If the index is not out of bound, return the value from the ArrayList.
What I have below works only when there is a "return" value in the Catch(). I know it is because the getter is asking to return a double. But I don't know how to fix this to behave the way stated above. Thank you so much!
Main Driver class for testing:
TestValue object = new TestValue();
System.out.println("The value is " + object.getListValue(8));
...other methods like print values, set new values etc.
TestValue class:
public double getListValue(int index) {
try {
listValue.get(index);
while (index <0 || index >= listValue.size()) {
}
}
catch (IndexOutOfBoundsException e) {
System.out.println(e.getMessage());
System.out.println("Can't get value. Will skip this request. ");
return listValue.get(0); // I don't want to return any values
}
return listValue.get(index);
}
This is because the definition of your method was public double,
you have to return a double unless you throw an exception.
If you really don't want to return a value, you can return 0.0.
If someone calls my method, I want to defensively deal with the problem. Usually I just return null.
I decided to implement a try catch but it looks like I just end up returning null anyway.
Can I write my try catch in such a way that at the end of method it doesn't return null?
Sample code, using peek on a Stack class.
public T peek()
{
T temp = null;
try
{
temp = array[size];
}
catch(Exception e)
{
}
return temp;
}
When called with an empty stack. It will return null.
So should I even bother with the try catch for this kind of case? I am tempted to do this:
if(isEmpty())
return null;
If the stack is not empty I want to return the element. If the stack is empty then can I avoid returning null if I use the try-catch?
This is how I would approach the problem. By throwing an exception in the peek function, putting the duty of handling that exception in the caller. Why? Because I want an error to cause an explosion as big as possible. The peek method also became smaller. Also as you already agree on, returning null is lame.
public T peek() throws IndexOutOfBoundsException
{
return array[size];
}
and
try
{
T top = thestack.peek();
/* Do something with that object */
}
catch(IndexOutOfBoundsException e)
{
/* Do something else */
}
The method has to return something or throw an Exception. If you have an unbounded generic type, then things like null object patterns can't be used, so the options are returning null, returning something that contains T like Optional<T>, or throwing an Exception.
If you don't like the safety of null, you can use Optional, either from Java 8 or a library. Checked exceptions have a similar safety but are inappropriate here.
It's hard to imagine the array[size] throwing an Exception, unless array is null or size is outside the length of array. So, you could do something like this -
if (array != null && array.length > size) {
return array[size - 1]; // assuming your size starts at 1
}
return null; // need to return something, if not null you need an option type.
Edit
Or, using an Option monad - and something like,
if (array != null && array.length > size) {
return new Some<T>(array[size - 1]); // assuming your size starts at 1
}
return new None<T>();
This compiles:
class Ex1 {
public int show() {
try {
int a=10/10;
return 10;
}
catch(ArithmeticException e) {
System.out.println(e);
}
finally {
System.out.println("Finally");
}
System.out.println("hello");
return 20;
}
}
on the other hand this doesn't:
class Ex15 {
public int show() {
try {
int a=10/0;
return 10;
}
catch(ArithmeticException e) {
System.out.println(e);
}
finally {
System.out.println("Finally");
return 40;
}
System.out.println("hello");
return 20;
}
}
and gives unreachable statement System.out.println("hello"); error. why is it so?
The finally has a return so you are probably getting an unreachable code block error.
finally
{
System.out.println("Finally");
return 40;
}
System.out.println("hello"); // unreachable code
return 20;
This is actually a compile-time error in Java. See section 14.20.
It is a compile-time error if a
statement cannot be executed because
it is unreachable.
It's unreachable code. According to the compiler, System.out.println("hello"); can never be executed.
Beside that, DON'T EVER write return within a finally block. (see Hidden Features of Java for why you should not).
EDIT:
Yes, but what makes return in finally
do this?
It's not because it is in a finally block or something. Even if you'd remove the finally keyword, you will still get the error.
class ex15 {
public int show() {
int a = 10 / 0;
return 40;
System.out.println("hello");
return 20;
}
}
Obviously, if you return 40, there is no way you can execute the next line. finally just means "do always, no matter what". So.
When you put a "return" in the "finally" block, anything that comes after it will never be executed. The "return" statement ends the method right there.
You would get the same error if you put a System.out.println() in the first method, after the "return" statement in it.
You have a return in the finally block. This makes any statements after that unreachable. Also you have a return in the try block and again in the finally block. This doesn't make sense.