I'm using a try-catch block to catch any exceptions that might be thrown when I run certain methods on a stack. My code for the pop method looks like this:
public T pop()
{
T temp = null;
try
{
temp = first.data;
}
catch(Exception e)
{
System.out.println("Invalid operation on an empty stack");
}
first = first.next;
return temp;
}
When I run the program the exception is caught... my terminal produces this:
(menu choice 'd' is the pop method)
Please enter a menu choice: d
Invalid operation on an empty stack
Exception in thread "main" java.lang.NullPointerException
at MyStack.pop(MyStack.java:58)
at StackTest.main(StackTest.java:52)
so I think my exception is being caught since it prints "Invalid operation...", but my program also terminates when the exception is thrown. Any help?
We have learned a very valuable lesson today: don't catch Exception without good reason.
The problem here is that first is coming back null, so we're going to throw that exception once we try to dereference it.
Let's look at it from a different angle. If first is null, we know we can't pop anything, so we should be throwing the exception instead.
public T pop() {
if(first == null) {
throw new EmptyStackException("Invalid operation on empty stack");
}
T value = first.data;
first = first.next;
return value;
}
Seems like there's another exception being thrown, after your catch block. It is very likely that first is null. That causes the catch block to be executed (because first.data is a null pointer exception), but it also causes another null pointer exception at
first = first.next;
Thus you have an uncaught exception. How you tackle this is up to you; it's more of a design decision than a correctness one.
The simplest and probably correct option is to do all of your modification inside the try block, so if something goes wrong you don't resume operations that probably won't work.
public T pop(){
T temp = null;
try{
temp = first.data;
first = first.next;
}
catch(Exception e){
System.out.println("Invalid operation on an empty stack");
}
return temp;
}
Of course, the try..catch construction isn't really appropriate here. A much more succinct way to write the same method would be:
public T pop(){
if(first == null) return null;
//By virtue of reaching this point, first is necessarily non-null.
T temp = first.data;
first = first.next;
return temp;
}
But if the goal was to experiment with try..catch use my top answer.
first is clearly null based on your output. Now, you're catching the NullPointerException that arises from temp = first.data, but not the one that arises from first = first.next (since that assignment is not enclosed with a try block):
public T pop()
{
T temp = null;
try
{
temp = first.data; // <-- you catch the exception thrown here
}
catch(Exception e)
{
System.out.println("Invalid operation on an empty stack");
}
first = first.next; // <-- but you don't catch the one thrown here
return temp;
}
In general it's a very bad idea to catch a NullPointerException; explicitly check for null beforehand.
It's highly likely that your first is null.
Try this code instead
public T pop()
{
T temp = null;
try
{
if (first != null)
{
temp = first.data;
first = first.next;
}
}
catch(Exception e)
{
System.out.println("Invalid operation on an empty stack");
}
return temp;
}
Related
I have been working on this code for hours how can I throw a NoSuchElement exception so that it stops the loop when it reaches the beginning of the list right now here is what the test case outputs with my code
expected: but was:
Expected :a
Actual :z
* Returns the data from next element in the set.
* #return the data from next element in the set
*/
public E next() {
// TODO : Implement
//returns the next element in the collection and advances
// the iterator by one location (updating both internal references).
// If one were to call next(), then prev(), then next(), the results of the two next() calls should be identical.
E temp = this.nextElem.info;
if (this.nextElem != null) {
//throw new NoSuchElementException("No element found");
return temp;
}
if (temp != nextElem.info) {
//E temp2 = this.nextElem.info;
//nextElem = nextElem.next;
//return temp2;
throw new NoSuchElementException();
} else {
return temp;
}
code
What about just doing the following?
public E next() {
E temp = this.nextElem;
if (temp != null) {
return temp.info;
} else {
throw new NoSuchElementException();
}
}
Edit:
Sorry, I forgot to explain what went wrong in your code.
What exactly will be null when you reach the end of the loop? Will this.nextElem be null? Because if so, you will already get a NullPointerException in the line E temp = this.nextElem.info;. Or, will this.nextElem.info be null?
Carefully read through your code. At first, you are assigning this.nextElem.info to the variable temp. Later, you are comparing temp to nextElem.info in the if-statement. Keep in mind that this.nextElem.info and nextElem.info are usually synonymous. Hence, what you are effectively doing is the following: if (nextElem.info != nextElem.info) {. As you can see, the condition will always evaluate to falseand you will always go into theelsebranch and never reach yourthrow`.
Consider that one of only two things can occur when the method is called:
throw an exception because there is no next element
return the next element and advance the cursor
So your algorithm could be summarized as:
public E next() {
// throw an exception because there is no next element
if there is no next element
throw exception
endif
// return the next element and advance the cursor
let info be the info at the next element
advance the cursor to next element
return info
}
How this is actually implemented depends on implementation details you have not provided. This appears to be a class assignment so pseudo-code should be sufficient to get you going. Note that the order of operations matters. For instance, if there is no next element then you shouldn't be trying to capture the value at the next element.
This question already has answers here:
Java Compiler Error: Missing Return Statement
(2 answers)
Closed 4 years ago.
I'm using the code below in a Triangle class to allow the user to set the first, second, or third point of a declared Triangle.
public Point get(String p) throws IllegalArgumentException {
IllegalArgumentException e = new IllegalArgumentException();
try {
if (p == "first") { return first; }
else if (p == "second") { return second; }
else if (p == "third") { return third; }
else { throw e; }
}
catch (e) {
System.out.println("Error: " + e);
}
}
The compiler is telling me:
Triangle.java:41: error: missing return statement
}
^
But I thought the point of the catch statement was to be able to catch an error and return a string describing the error, without having to worry about matching the function's return type.
Because you're missing a return statement.
The method declares that it returns something, so it must return something (or throw an exception). The compiler can't guarantee that any of the return statements in the try block will be reached if an exception is thrown before any of them execute. So the catch block also needs to return something (or throw an exception, or return something after the try/catch construct entirely).
Edit: Looking again, you're also potentially missing a return in the try block. (If you don't have one after the entire try/catch structure.) What if none of the conditions in the if/else structure are satisfied? Nothing is returned. Which is invalid.
Basically, all logical paths must result in a valid exit of the method. You've missed two such paths.
You're not returning anything in your function on several paths.
But I thought the point of the catch statement was to be able to catch an error and return a string describing the error, without having to worry about matching the function's return type.
That's not at all what a try-catch does, and moreover your function is declared to return a Point not a String.
try-catch simply "catches" a Throwable (Error or Exception) and allows you to run some code when it is thrown instead of simply terminating the application with an Uncaught Exception/Error.
You need to return some value from your function after the try-catch there is no way to return a string, nor is there a language construct in place that behaves like you've explained your understanding of try-catch.
Also your code cna't actually throw an IllegalArgumentException so your catch block will never get called. In this case, it sounds like what you want is instead something like this
public Point get(String p) throws IllegalArgumentException {
if (p == null) { throw new IllegalArgumentException(); }
if (p.equals("first")) { return first; }
else if (p.equals("second")) { return second; }
else if (p.equals("third")) { return third; }
else { throw new IllegalArgumentException(); }
}
The code could then be called like so
Point p;
try {
p = get("notFirst");
} catch (IllegalArgumentException ex) {
//oh no, we gave a bad argument, and the method told us nicely.
}
You are missing two parts:
1. A return statement in try block for else condition
2. Catch block doesn't lead to a return statement or a throw statement
I don't know if type of first, second, third variables are string or Point, but you should return with Point, because your function is :
public Point get(String p) {
...
}
You have three if statements. What happens when the input doesn't satisfy any of those? Your method doesn't have a return statement for that case.
I'm writing Deque class on Java, according to Algorithms, Part 1 on Coursera. And currently my array-based Deque has method removeLast():
public Item removeLast() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head != tail) {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
throw new NoSuchElementException("Stack underflow");
}
If head == tail means Deque is empty and I throw exception, according to homework specification, at the end of method instead of return statement. This code gives direct intention about invariants (head != tail).
On the other hand method may be rewritten like this:
public Item removeLastRewritten() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head == tail) {
throw new NoSuchElementException("Stack underflow");
}
Item tmp = array[--head];
array[head] = null;
return tmp;
}
In my opinion removeLast is more clearly written by these reasons:
Adhere to pessimistic scenario - always fail, only if ... which is more reliable approach, especially when method code will enlarge and become more complicated.
Gives more clear link between invariant tail != head and subsequent if {} code block.
I have the following questions:
Which is a better approach?
Is it considered an appropriate/good practice to write like removeLast?
What is considered a best practice for Java? Is there any code style about it (I couldn't find any)?
There is not a wrong answer. In GrepCode you can find every flavour you propose:
Inside a if with the != operator and at the end of the method:
E java.util.PriorityQueue.next()
public E More ...next() {
if (... != ...)
throw new ConcurrentModificationException();
...
if (...) {
return lastRetElt;
}
throw new NoSuchElementException();
}
Inside a if with the == operator
E org.fluentlenium.core.domain.FluentList.first()
public E More ...first() {
if (this.size() == 0) {
throw new NoSuchElementException("Element not found");
}
return this.get(0);
}
The reason why it looks weird is because you omit the else block of your if block, which would incorporate either leftover that comes after the if block in both your methods. The reason you can get away with it here is because the thrown exception will disrupt the flow of your method.
I think it's better not to rely on that and just be nice and use the if-else blocks intuitively.
public Item removeLastRewrittenAgain() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head != tail) { // invert the if-else block if preferred, it would not make any difference
Item tmp = array[--head];
array[head] = null;
return tmp;
} else {
throw new NoSuchElementException("Stack underflow");
}
}
Another reason why I don't really like to throw exceptions before the end of a method is that I strongly believe in and thus thoroughly use the concept of a single point of exit, meaning I don't leave the method somewhere in the middle which I believe is more difficult to read for someone not familiar with the code.
One place to return your value (or thrown exceptions): the very bottom of your method.
Your code becomes more readable if you explicitly mention the else, regardless of your choice.
Then there is the dilemma of
if (head != tail) {
Item tmp = array[--head];
array[head] = null;
return tmp;
} else {
throw new NoSuchElementException("Stack underflow");
}
versus
if (head == tail) {
throw new NoSuchElementException("Stack underflow");
} else {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
Here I strongly prefer the second one. When I'm reading the "complicated part" of the if statement, I want to know why I'm actually inside an if. When reading the first variant the whole reason for the if only becomes apparent when you're throwing the exception.
I guess you could also solve that by writing
boolean isEmpty = head == tail;
if (!isEmpty) {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
throw new NoSuchElementException("Stack underflow");
but I prefer the version that throws the exception as soon as you know something is wrong.
So I'm trying to catch exceptions where I can't return a Directory, but Java won't let me. How do I structure the code so that Java will let me run it?
public Directory pathToDir(String path) throws Exception {
String[] arrayPath = path.split("/");
Directory cwd_copy = FileSystem.getRoot();
try {
// full path
if (path.startsWith("/")) {
for (int x = 1; x < arrayPath.length; x++) {
if (stuff) {
} else {
throw new Exception();
}
}
}
return cwd_copy;
}
catch (Exception e) {
pathErrorMsg();
}
}
No, you may be throwing an exception, but then you catch it and do nothing with it! If you step through that code logically, you'll see that there are possible pathways for the method to end without a Directory being returned and for no exceptions to be thrown. That won't fly.
Consider instead,....
public Directory pathToDir(String path) throws PathToDirException {
String[] arrayPath = path.split("/");
Directory cwd_copy = FileSystem.getRoot();
// full path
if (path.startsWith("/")) {
for (int x = 1; x < arrayPath.length; x++) {
if (stuff) {
} else {
throw new PathToDirException( /* some text goes in here! */ );
}
}
}
return cwd_copy;
}
Where PathToDirException is a checked exception class you've created for problems with this method/class.
Or if you have a try/catch block in the method, and need to then throw an exception, throw your new Exception class, but pass the caught exception into your new exception as a constructor parameter.
If I understand your question, you need a return at the end of your method (in case you catch an Exception instead of returning cwd_copy)
return cwd_copy; // <-- this didn't happen.
} catch (Exception e) {
pathErrorMsg();
// return null; // <-- you could return here.
}
return null; // <-- so you need something. null or cwd_copy
Or add a return in the catch block.
Because an exception could be caught1, a value must still be returned from the catch path.
try {
maybeThrowException();
return X;
}
catch (Exception e) {
// But what is returned here?
}
Either don't catch the exception, [re]throw an exception, or return a value in the case when the catch block is entered.
Since the method is declared to throw an Exception, it probably should throw one on failure - the method contract should specify the result in such a case.
1 Java actually isn't that smart, even if it is a logical way to think about it. The try/catch is treated like an if/else here and all branches must logically lead to a return (or throw). It would still be a compiler error even if the try was empty and could never throw an exception. Consider the following comparison:
if (true) {
return X;
} else {
// But what is returned here?
// (Java does not consider that this can never be reached,
// just as it does not logically consider the content of a `try`.)
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I tried using try-catch block to catch NullPointerException but still the following program is giving errors. Am I doing something wrong or is there any other way to catch NullPointerException in the following program. Any help is highly appreciated.
public class Circular_or_not
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
try
{
LinkedListNode[] nodes = new LinkedListNode[10];
for (int i = 0; i < 10; i++)
{
nodes[i] = new LinkedListNode(i, null, i > 0 ? nodes[i - 1] : null);
}
// Create loop;
// nodes[9].next = nodes[3];
Boolean abc= Check_Circular(nodes[0]);
System.out.print(abc);
}
catch(NullPointerException e)
{
System.out.print("NullPointerException caught");
}
}
public static boolean Check_Circular(LinkedListNode head)
{
LinkedListNode n1 = head;
LinkedListNode n2 = head;
// Find meeting point
while (n2.next != null)
{
n1 = n1.next;
n2 = n2.next.next;
if (n1 == n2)
{
return true;
}
}
return false;
}
}
NullPointerException is a run-time exception which is not recommended to catch it, but instead avoid it:
if(someVariable != null) someVariable.doSomething();
else
{
// do something else
}
As stated already within another answer it is not recommended to catch a NullPointerException. However you definitely could catch it, like the following example shows.
public class Testclass{
public static void main(String[] args) {
try {
doSomething();
} catch (NullPointerException e) {
System.out.print("Caught the NullPointerException");
}
}
public static void doSomething() {
String nullString = null;
nullString.endsWith("test");
}
}
Although a NPE can be caught you definitely shouldn't do that but fix the initial issue, which is the Check_Circular method.
The problem with your code is in your loop in Check_Circular. You are advancing through the list using n1 by going one node at a time. By reassigning n2 to n2.next.next you are advancing through it two at a time.
When you do that, n2.next.next may be null, so n2 will be null after the assignment. When the loop repeats and it checks if n2.next is not null, it throws the NPE because it can't get to next since n2 is already null.
You want to do something like what Alex posted instead.
I think your problem is inside CheckCircular, in the while condition:
Assume you have 2 nodes, first N1 and N2 point to the same node, then N1 points to the second node (last) and N2 points to null (because it's N2.next.next). In the next loop, you try to call the 'next' method on N2, but N2 is null. There you have it, NullPointerException
You should be catching NullPointerException with the code above, but that doesn't change the fact that your Check_Circular is wrong. If you fix Check_Circular, your code won't throw NullPointerException in the first place, and work as intended.
Try:
public static boolean Check_Circular(LinkedListNode head)
{
LinkedListNode curNode = head;
do
{
curNode = curNode.next;
if(curNode == head)
return true;
}
while(curNode != null);
return false;
}