I read code from one book and have this method:
public int getScore(String name) {
try {
//some code here
return score;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
Why this method in catch returns -1? Why not 5? Is that some convention?
-1 is a standard error code when the caller expects a positive int
but really in that case a wrapped RuntimeException or a more specific one would have been much better
I'm assuming the author uses this code to make sure something gets returned, and the caller of getScore can check to see if a score was correctly called.
In code:
int theScore = getScore("My Name");
if(theScore == -1) {
// Oh no, there was an error!
}
We can use the check for -1 to make sure that the code knows when getScore fails.
Why method returns -1?
Because it is very poorly designed to do so on any exception. The method would have been better designed by declaring it to throw the exception(s) of interest and specifically by not catching all the RuntimeExceptions as well.
You are the one choosing what you want to return as you are the only one who knows how you want to handle that returned value. I personally use -1 too when I want to detect an error, and I know a lot of people doing the same.
The reason they picked -1 instead of 5 is because -1 is not a feasible score to return from the getScore method. Therefore, when you call the function, you can easily check if it was -1 returned or not.
If it was a function that could realistically return -1 for a successful run, -1 would be a poor choice of a flag indicator. A more appropriate choice, then, might be -9999 or something ridiculous.
The first problem is we don't know what the exceptions are. Catching every exception is a very poor decision. Those exceptions were thrown for a reason so you would know exactly what went wrong and can deal with it appropriately.
Bad:
public int getScore(String name) {
try {
int score = scores.getScoreForName(name);
return score;
} catch (Exception e) { // catches everything
e.printStackTrace();
return -1;
}
}
Marginally better...
public int getScore(String name) {
try {
int score = scores.getScoreForName(name);
return score;
} catch(NameNotFoundException) {
e.printStackTrace();
return -2; // now we know what happened, not just a general error
} catch (Exception e) { // catches everything
e.printStackTrace();
return -1; // generally error
}
}
Much better:
/**
* Get the score for a given name. Will throw a runtime exception if the
* name doesn't exist.
* #param name The name to get the score for
* #return the score for the name
* #throws NameNotFoundException if the name doesn't exist in the database.
*/
public int getScore(String name) {
return scores.getScoreForName(name);
}
Related
I have a method that receives a string and then returns an enum. I want to print an error message if the string matches none of the regexes. The only problem is that the method requires me to return something. I could return null, but that means I have to check for null once the enum has been returned. I was wondering if there was an easy and more conventional way to handle this? I want to catch the exception as I don't want the program to crash.
public static Direction getDirection(String direction) {
try {
direction = direction.toLowerCase();
if (direction.matches("go\s+[n]|go\s+north|north|[n]")) {
return NORTH;
} else if (direction.matches("go\s+[s]|go\s+south|south|[s]")) {
return SOUTH;
} else if (direction.matches("go\s+[w]|go\s+west|west|[w]")) {
return WEST;
} else if (direction.matches("go\s+[e]|go\s+east|east|[e]")) {
return EAST;
} else {
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException unknownCommand) {
System.out.println("Unknown Command");
}
}
```
I would go for null. Java does not guarantee that a given object is not null at a given point in time, so you actually need to do null-checks frequently if you really want to avoid NPEs at all costs.
If you definitely want to avoid null, then I would go with a new Enum value for Direction. Something like UNDEFINED or UNDETERMINED or UNKNOWN or INVALID.
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.
What's in java the correct method to handle method params/inner errors?
All the three methods do the same thing, with a little difference in the second one where exception also have a "caused by" section.
Please not that in the third method, the return must be repeated every time i want to exit from it.
Consider also that exception handling is quite expensive in java (i've read this somewhere).
Thanks!!
public static String method(String arg) {
block: {
if (arg == null) {
logger.error("arg is null");
break block;
}
try {
...
return "ok";
} catch (Exception e)
logger.error("help!", e);
}
}
return "ko";
}
public static String method(String arg) {
try {
if (arg == null) {
throw new Exception("arg is null");
}
...
return "ok";
} catch (Exception e) {
logger.error("help!", e);
return "ko";
}
}
public static String method(String arg) {
String result = "ko";
if (arg == null) {
logger.error("arg is null");
return result;
}
try {
..
result = "ok";
} catch(Exception e) {
logger.error("help!", e);
}
return result;
}
EDIT:
Also, in the second method, you can differentiate inner method errors by using RuntimeException (or a custom one), bad idea?
I don't think the "right" way is any of these 3.
Java has an exception just for invalid parameters, called IllegalArgumentException, which is actually a RuntimeException, so you don't declare it. The idea is that if you provide an illegal argument, this is a bug in the caller side, so the caller must catch and deal with the exception.
When your method returns a valid result for an "illegal" argument, IMO, your argument is not really illegal, so there shouldn't be an exception and then there's nothing to recover from. And so, your code should look like
public static String method(String arg) {
return arg==null?"ko":"ok";
}
No exceptions here.
Now, if a null argument is something exceptional that you have to deal with, I think the right approach is to treat it in the caller side. In the JDK, you'll find examples of both explicit and implicit invalid argument exceptions, for example:
Explicit
* #param s the string to be parsed.
* #return a {#code Double} object holding the value
* represented by the {#code String} argument.
* #throws NumberFormatException if the string does not contain a
* parsable number.
*/
public static Double valueOf(String s) throws NumberFormatException {
return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue());
}
Implicit
* #param uri
* the URI to convert
*
* #return the resulting {#code Path}
*
* #throws IllegalArgumentException
* if preconditions on the {#code uri} parameter do not hold. The
* format of the URI is provider specific.
(...)
*/
public static Path get(URI uri) {
String scheme = uri.getScheme();
if (scheme == null)
throw new IllegalArgumentException("Missing scheme");
(...)
I think the whole idea here is
if a null arg is an exceptional situation, not expected by your method, then it's a bug and you must recover from it outside the called method. If the called method can deal with the null arg (returning for example some valid value such as "ko") then it's not an exceptional situation, but just a valid argument for which there's a valid result, so no exceptions are needed here.
otherwise, you must throw an exception (explicit or not) and let the caller deal with it
That's what I think.
Up for the first one, cause it's more elegant, but third one is more clear to read and less error prone imho.
You should use the one that is easiest to read. Remember that code is written once and read many times.
The third one is the most easiest to read.
Another rule which is pretty good. One entry one exist for every method.
It is preferable to only use one return statement.
The reason is that it is easier for the next reader to understand what the thought is with the code.
More about this kinds of issue, you can read about in Clean Code http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
Suggestion for one entry-exist solution:
public static String method(String arg) {
String outString = "ko";
try {
if (arg != null) {
outString = "ok";
} else {
logger.debug("arg is null");
}
} catch (Exception e) {
logger.error("Help!", e);
}
return outString;
}
Is there a way to end the method that calls on the method that the code is in. Let me explain if you have some code like this.
int value;
value = method();
value = 3;
If I got it work like I want then the execution of the code would end on line 2 and line 3 would never be executed. basically it would be like there was a return between line 2 and 3. Is is something like this possible with Java?
Edit: Ok i think a lot of people have misunderstood me. The code that end the code on in this method on line 2 should be inside of method() and it should not be possible to avoid this outside this method if it's call inside of a try for example.
Your example is a bit abstract, a real one might result in better answers. In general though there are two ways this is normally achieved:
Return a special value e.g. -1
int method() {
if (/* something is wrong */) {
return -1;
}
// Process as normal and return real value
}
...
int value;
value = method();
if (value == -1) {
value = 3;
}
Throw an exception in method()
int method() throws IllegalStateException {
if (/* something is wrong */) {
throw new IllegalStateException();
}
// Process as normal and return real value
}
...
int value;
try {
value = method();
} catch (IllegalStateException e) {
value = 3;
}
You can terminate the current program / JVM with System.exit
java.lang.System.exit(0 /* Status */ );
If you don't want to exit then you have to use return.
in a void method do
int value;
value = method();
return;
Or if method has the same return signature as the current method
int value;
return value = method();
Add if condition value=youexpected return;
I would like to retry calling a function in the exception clause like this:
private int mTries = 0;
private void myFunction() {
try {
// do something
} catch (Exception e) {
if (mTries ++ < MAX_TRIES;
myFunction();
}
}
}
My question, regardless the stack memory usage, calling a function recursively in the catch clause the same as calling it in normal case? I am wonder if doing this will blow off the stack, if my app is running on android platform.
private void anotherFunction(int i) {
if (i == 0)
return;
anotherFunction(i--);
}
Why not write it like this?
private void myFunction(){
int triesRemaining = MAX_TRIES;
while( triesRemaining-- > 0 ){
try{
// ... do stuff
return;
}
catch( Exception e ){
}
}
throw new Exception( "too many failures" );
}
However, I seriously recommend you narrow down the catch clause so that you only catch only those types of exception after which you'd want to continue processing.
Your second implementation will always cause a stack overlflow. (Try passing in a value even of 1, it will fail).
My question, regardless the stack memory usage, calling a function recursively in the catch clause the same as calling it in normal case?
Yes, it is exactly the same.