Can we use "catch" to handle OutOfBoundsException with specific value? - java

I'm learning about exceptions in java. I have come across the following problem:
String bigstring = myscanner.nextLine();
String[] splited = bigstring.split("\\s+");
try {
smallstring1 = splited[0];
smallstring2 = splited[1];
smallstring3 = splited[2];
} catch(java.lang.ArrayIndexOutOfBoundsException exc) {
smallstring3 = null;
}
This would work if the user wants to type 2 words only.
What if he wants to type one word?
Can we somehow specify a value which we get in error after the colon?
Like:
java.lang.ArrayIndexOutOfBoundsException: 2
or
java.lang.ArrayIndexOutOfBoundsException: 1
Can we somehow use (for this example) this "2" or "1" in try/catch block?

java.lang.ArrayIndexOutOfBoundsException is not a exception designed to be recoverable. It conveys a programming error.
So rather than trying to understand the index that causes problem in the catch, you should rather ensure that the exception doesn't occur.
In your case you should check the size of the array before trying to get the value of it.
Here is an example :
int arraySize = splited.length;
if (arraySize == 3){
smallstring1=splited[0];
smallstring2=splited[1];
smallstring3=splited[2];
}
else if (arraySize == 2){
smallstring1=splited[0];
smallstring2=splited[1];
}
else if (arraySize == 1){
smallstring1=splited[0];
}

You probably shouldn't use exceptions for normal program flow. Exceptions should usually be "exceptional".
Anyway, although you cannot do that, you can use if statements inside your catch block. You can also check splited.length to check how big the array is.

Related

Half String every second char

I an coding beginner.I have started practicing SPOJ basic problems.This was the one I was trying to solve , But the code is incorrect.
Please help me where I have coded this question wrong as I am unable to figure out:
public class Print2ndChar {
public static void main(String[] args) throws java.lang.Exception {
Print2ndChar mainObj = new Print2ndChar();
java.io.BufferedReader inputReader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
String noOfTestCase;
if(((noOfTestCase = inputReader.readLine()) == null))
System.exit(0);
int noOfLines = 0;
try{
noOfLines = Integer.parseInt(noOfTestCase);
}catch(Exception e){
System.exit(0);
}
if(noOfLines<0 || noOfLines>100)
System.exit(0);
String [] randomWords = new String[noOfLines];
for(int i=0;i<noOfLines;i++){
randomWords[i] = inputReader.readLine();
if(randomWords[i] == null || randomWords[i].length()<2 || randomWords[i].length()%2!=0 || (randomWords[i].length()/2)>100)
System.exit(0);
}
for (String word : randomWords){
mainObj.letsBegin(word.substring(0, word.length() / 2));
System.out.println();
}
}
private void letsBegin(String data) {
if (data.length() <= 0) {
return;
} else {
System.out.print(data.charAt(0));
if (data.length() >= 3)
letsBegin(data.substring(2, data.length()));
}
}
}
EDIT :
I/P : 4
your
progress
is
noticeable
O/P
y
po
i
ntc
OK! So after a lot of hit and trials, I know what is wrong with your code. The code that you have written fails because of the condition randomWords[i].length()%2!=0 inside your if. There is nothing wrong with you putting this condition to check the input, but if you will select sample test case, inside the highlighted blue area you will notice an extra space after every string. Like this :
You can see that other than the last input all other input strings have a space character at the end. So, when you read the string from stdin the length of the string is 2*k + 1 (because of the space), and your program will exit without any output. Hence you get a wrong answer.
This problem exists with other test cases as well probably. And how do I know this? After spoj shows you wrong answer, if you click on the wrong answer, it will show you 2 failed test cases, something like this:
It shows your program's output is empty because your code exited because of the extra space at the end of strings.
So, I believe the person who wrote the test cases should be given a WT Error (Wrong Test Cases) :P :D
So, the possible correction is you remove the mentioned condition from the if and you will get AC. Because now you will be dividing 2*k + 1 by 2, which will not be an integer and which will get rounded to the nearest smallest integer, which will be same as dividing 2*k by 2 and the program will give the correct result.
A few things that you should take care while solving questions on spoj, you do not have to verify that every input lies within the range specified in the question, or if it is a valid data type. The range is given to tell you that Spoj will only test your program with cases which lie between those ranges and will not exceed them. So, even if you remove all the code where you check for exceptions and ranges of input data, you will get an AC. Moreover, writing such code only adds to the burden.
Hope this helps. :)

Recursive grep with good efficiency

This question is very specific to me, so I cannot find related questions on Stack Overflow. So, I'm coding a grep shown below. I am confused on the stringindextoutofboundexception. The reason for that is because I am checking whether it is equals to \0. That means I am handling the out of bound exception, no?
Example:
grep("hello","llo");
This will return 3. That is because its start matching at original[2] which is position 3. However, I am encountering an out of index error. I've spent hours and I can't figure it out.
public static int grep(String ori, String ma){
int toReturn = 0;
int oCounter = 0;
int i = 0;
while (i < ma.length()){
if (ori.charAt(toReturn) == ma.charAt(i)){
i++;
if (ma.charAt(i) == '\0'){ // error on this line
return toReturn;
}
toReturn++;
if (ori.charAt(toReturn) == '\0'){ // and this line if i delete the section above.
return -1;
}
} else {
i = 0;
toReturn++;
}
}
return -1;
}
You're getting an StringIndexOutOfBoundsException because you increment i inside the loop at a too early and wrong stage.
Checking for \0 is a C++ thing. Strings in java are not \0 terminated.
What you're writing is already done in the String class. There are several methods available.
System.out.println("hello".indexOf("llo"));
will print 2 because it's been found and starts at index 2. Feel free to add 1 if you dislike the starting at 0 for some reason.
You also ask "that means I'm handling the exception, no?". No, it doesn't. Exceptions are handled with a special syntax called try-catch statements. And example:
try {
// possibly more lines of code here
do_something_that_might_cause_exception();
// possibly more lines of code here
} catch (Exception e) {
// something did indeed cause an exception, and the variable e holds information about. We can do "exceptional" handling here, but for now we print some information.
e.printStackTrace();
}

if statement with integers [duplicate]

This question already has answers here:
Why does my if condition not accept an integer in java?
(7 answers)
Closed 3 years ago.
I'm new at Java. I'm looking for some help with homework. I wont post the full code I was doing that originally but I dont think it will help me learn it.
I have a program working with classes. I have a class that will validate a selection and a class that has my setters and getters and a class that the professor coded with the IO for the program (it's an addres book)
I have a statement in my main like this that says
//create new scanner
Scanner ip = new Scanner(System.in);
System.out.println();
int menuNumber = Validator.getInt(ip, "Enter menu number: ", 1, 3);
if (menuNumber = 1)
{
//print address book
}
else if (menuNumber = 2)
{
// get input from user
}
else
{
Exit
}
If you look at my if statement if (menuNumber = 1) I get a red line that tells me I cannot convert an int to boolean. I thought the answer was if (menuNumber.equals(1)) but that also gave me a similar error.
I'm not 100% on what I can do to fix it so I wanted to ask for help. Do I need to convert my entry to a string? Right now my validator looks something like:
if (int < 1)
print "Error entry must be 1, 2 or 3)
else if (int > 3)
print "error entry must 1, 2, or 3)
else
print "invalid entry"
If I convert my main to a string instead of an int wont I have to change this all up as well?
Thanks again for helping me I haven't been diong that great and I want to get a good chunk of the assignment knocked out.
if (menuNumber = 1)
should be
if (menuNumber == 1)
The former assigns the value 1 to menuNumber, the latter tests if menuNumber is equal to 1.
The reason you get cannot convert an int to boolean is that Java expects a boolean in the if(...) construct - but menuNumber is an int. The expression menuNumber == 1 returns a boolean, which is what is needed.
It's a common mix-up in various languages. I think you can set the Java compiler to warn you of other likely cases of this error.
A trick used in some languages is to do the comparison the other way round: (1 == menuNumber) so that if you accidentally type = you will get a compiler error rather than a silent bug.
This is known as a Yoda Condition.
In Java, a similar trick can be used if you are comparing objects using the .equals() method (not ==), and one of them could be null:
if(myString.equals("abc"))
may produce a NullPointerException if myString is null. But:
if("abc".equals(myString))
will cope, and will just return false if myString is null.
I get a red line that tells me I cannot convert an int to boolean.
Thats because = is an assignment operator. What you need to use is == operator.
A single equal sign is assignment: you assign value to a variable this way. use two equal signs (==) for comparison:
if ($menuNumber = 1) {
Update: forgot dollar sign: $menuNumber

How can I remove the while(true) from my loop in Java?

I've heard that using while(true) is a bad programming practice.
So, I've written the following code to get some numbers from a user (with default values). However, if the user happens to type in -1, then it will quit the program for them.
How should this be written then without a while(true)? I can think of a condition to make the while loop go off that will get caught right away without continuing on until the next iteration?
Here is how I have it now:
public static void main(String[] args)
{
System.out.println("QuickSelect!");
while (true)
{
System.out.println("Enter \"-1\" to quit.");
int arraySize = 10;
System.out.print("Enter the size of the array (10): ");
String line = input.nextLine();
if (line.matches("\\d+"))
{
arraySize = Integer.valueOf(line);
}
if (arraySize == -1) break;
int k = 1;
System.out.print("Enter the kth smallest element you desire (1): ");
line = input.nextLine();
if (line.matches("\\d+"))
{
k = Integer.valueOf(k);
}
if (k == -1) break;
List<Integer> randomData = generateRandomData(arraySize, 1, 100);
quickSelect(randomData, k);
}
}
while (true) is fine. Keep it.
If you had a more natural termination condition, I'd say to use it, but in this case, as the other answers prove, getting rid of while (true) makes the code harder to understand.
There is a Single Entry Single Exit (SESE) school of thought that suggests that you should not use break, continue or abuse exceptions to do the same for some value of abuse). I believe the idea here is not that you should use some auxiliary flag variable, but to clearly state the postcondition of the loop. This makes it tractable to formerly reason about the loop. Obviously use the stands-to-reason form of reasoning, so it is unpopular with the unwashed masses (such as myself).
public static void main(String[] args) {
...
do {
...
if (arraySize == -1) {
...
if (k != -1) {
...
}
}
} while (arraySze == -1 || k == -1);
...
}
Real code would be more complex and you would naturally(!) separate out the inputing, outputting and core "business" logic, which would make it easier to see what is going on.
bool exit = false;
while (!exit) {
...
...
if (k == -1) {
exit = true;
}
else {
List <Integer> ....;
quickselect(.......);
}
}
But as has been said before, your while loop is a valid usage in this situation. The other options would simply build upon the if statements to check for the boolean and exit.
While having a loop like this is not technically wrong, some people will argue that it is not as readable as the following:
bool complete = false;
while (!complete)
{
if (arraySize == -1)
{
complete = true;
break;
}
}
Additionally, it is sometimes a good idea to have a safety loop counter that checks to make sure the loop has not gone through, say, 100 million iterations, or some number much larger than you would expect for the loop body. This is a secure way of making sure bugs don't cause your program to 'hang'. Instead, you can give the user a friendly "We're sorry but you've discovered a bug.. program will now quit.." where you set 'complete' to true and you end the program or do additional error handling. I've seen this in production code, and may or may not be something you would use.
while ( true ) is perfectly fine here, since the condition is really "while the user doesn't want to quit"!
Alternatively you could prompt for both the inputs on one line to simplify the logic, and use "q" for quit: this allows you to refactor the loop to "while ( !line.equals("q") )".
The problem is that you're doing an awful lot in that loop, rather than separating the functionality into simple methods.
If you want to stick to a procedural approach, you could move the reading of the array size and k into separate methods, and use the fact that the result of an assignment is the assigned value:
for (int arraySize; ( arraySize = readArraySize ( input ) ) != -1;) {
final int k = readKthSmallestElement ( input );
List<Integer> randomData = generateRandomData(arraySize, 1, 100);
quickSelect(randomData, k);
}
However that's still a bit ugly, and not well encapsulated. So instead of having the two != -1 tests on separate variables, encapsulate arraySize, k and randomData in an object, and create a method which reads the data from the input, and returns either a QuickSelect object or null if the user quits:
for ( QuickSelect select; ( select = readQuickSelect ( input ) ) != null; ) {
select.generateRandomData();
select.quickSelect();
}
You might even want to go to the next stage of creating a sequence of QuickSelect objects from the input, each of which encapsulate the data for one iteration:
for ( QuickSelect select : new QuickSelectReader ( input ) ) {
select.generateRandomData();
select.quickSelect();
}
where QuickSelectReader implements Iterable and the iterator has the logic to create a QuickSelect object which encapsulates arraySize, k, the list and the quick select operation. But that ends up being quite a lot more code than the procedural variants.
I'd only do that if I wanted to reuse it somewhere else; it's not worth the effort just to make main() pretty.
Also note that "-1" doesn't match the regex "\\d+", so you really do have an infinite loop.
If you really don't like while(true) you can always go for for(;;). I prefer the latter because it seems less redundant.

Should try...catch go inside or outside a loop?

I have a loop that looks something like this:
for (int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
myFloats[i] = myNum;
}
This is the main content of a method whose sole purpose is to return the array of floats. I want this method to return null if there is an error, so I put the loop inside a try...catch block, like this:
try {
for (int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
myFloats[i] = myNum;
}
} catch (NumberFormatException ex) {
return null;
}
But then I also thought of putting the try...catch block inside the loop, like this:
for (int i = 0; i < max; i++) {
String myString = ...;
try {
float myNum = Float.parseFloat(myString);
} catch (NumberFormatException ex) {
return null;
}
myFloats[i] = myNum;
}
Is there any reason, performance or otherwise, to prefer one over the other?
Edit: The consensus seems to be that it is cleaner to put the loop inside the try/catch, possibly inside its own method. However, there is still debate on which is faster. Can someone test this and come back with a unified answer?
PERFORMANCE:
There is absolutely no performance difference in where the try/catch structures are placed. Internally, they are implemented as a code-range table in a structure that is created when the method is called. While the method is executing, the try/catch structures are completely out of the picture unless a throw occurs, then the location of the error is compared against the table.
Here's a reference: http://www.javaworld.com/javaworld/jw-01-1997/jw-01-hood.html
The table is described about half-way down.
Performance: as Jeffrey said in his reply, in Java it doesn't make much difference.
Generally, for readability of the code, your choice of where to catch the exception depends upon whether you want the loop to keep processing or not.
In your example you returned upon catching an exception. In that case, I'd put the try/catch around the loop. If you simply want to catch a bad value but carry on processing, put it inside.
The third way: You could always write your own static ParseFloat method and have the exception handling dealt with in that method rather than your loop. Making the exception handling isolated to the loop itself!
class Parsing
{
public static Float MyParseFloat(string inputValue)
{
try
{
return Float.parseFloat(inputValue);
}
catch ( NumberFormatException e )
{
return null;
}
}
// .... your code
for(int i = 0; i < max; i++)
{
String myString = ...;
Float myNum = Parsing.MyParseFloat(myString);
if ( myNum == null ) return;
myFloats[i] = (float) myNum;
}
}
All right, after Jeffrey L Whitledge said that there was no performance difference (as of 1997), I went and tested it. I ran this small benchmark:
public class Main {
private static final int NUM_TESTS = 100;
private static int ITERATIONS = 1000000;
// time counters
private static long inTime = 0L;
private static long aroundTime = 0L;
public static void main(String[] args) {
for (int i = 0; i < NUM_TESTS; i++) {
test();
ITERATIONS += 1; // so the tests don't always return the same number
}
System.out.println("Inside loop: " + (inTime/1000000.0) + " ms.");
System.out.println("Around loop: " + (aroundTime/1000000.0) + " ms.");
}
public static void test() {
aroundTime += testAround();
inTime += testIn();
}
public static long testIn() {
long start = System.nanoTime();
Integer i = tryInLoop();
long ret = System.nanoTime() - start;
System.out.println(i); // don't optimize it away
return ret;
}
public static long testAround() {
long start = System.nanoTime();
Integer i = tryAroundLoop();
long ret = System.nanoTime() - start;
System.out.println(i); // don't optimize it away
return ret;
}
public static Integer tryInLoop() {
int count = 0;
for (int i = 0; i < ITERATIONS; i++) {
try {
count = Integer.parseInt(Integer.toString(count)) + 1;
} catch (NumberFormatException ex) {
return null;
}
}
return count;
}
public static Integer tryAroundLoop() {
int count = 0;
try {
for (int i = 0; i < ITERATIONS; i++) {
count = Integer.parseInt(Integer.toString(count)) + 1;
}
return count;
} catch (NumberFormatException ex) {
return null;
}
}
}
I checked the resulting bytecode using javap to make sure that nothing got inlined.
The results showed that, assuming insignificant JIT optimizations, Jeffrey is correct; there is absolutely no performance difference on Java 6, Sun client VM (I did not have access to other versions). The total time difference is on the order of a few milliseconds over the entire test.
Therefore, the only consideration is what looks cleanest. I find that the second way is ugly, so I will stick to either the first way or Ray Hayes's way.
While performance might be the same and what "looks" better is very subjective, there is still a pretty big difference in functionality. Take the following example:
Integer j = 0;
try {
while (true) {
++j;
if (j == 20) { throw new Exception(); }
if (j%4 == 0) { System.out.println(j); }
if (j == 40) { break; }
}
} catch (Exception e) {
System.out.println("in catch block");
}
The while loop is inside the try catch block, the variable 'j' is incremented until it hits 40, printed out when j mod 4 is zero and an exception is thrown when j hits 20.
Before any details, here the other example:
Integer i = 0;
while (true) {
try {
++i;
if (i == 20) { throw new Exception(); }
if (i%4 == 0) { System.out.println(i); }
if (i == 40) { break; }
} catch (Exception e) { System.out.println("in catch block"); }
}
Same logic as above, only difference is that the try/catch block is now inside the while loop.
Here comes the output (while in try/catch):
4
8
12
16
in catch block
And the other output (try/catch in while):
4
8
12
16
in catch block
24
28
32
36
40
There you have quite a significant difference:
while in try/catch breaks out of the loop
try/catch in while keeps the loop active
I agree with all the performance and readability posts. However, there are cases where it really does matter. A couple other people mentioned this, but it might be easier to see with examples.
Consider this slightly modified example:
public static void main(String[] args) {
String[] myNumberStrings = new String[] {"1.2345", "asdf", "2.3456"};
ArrayList asNumbers = parseAll(myNumberStrings);
}
public static ArrayList parseAll(String[] numberStrings){
ArrayList myFloats = new ArrayList();
for(int i = 0; i < numberStrings.length; i++){
myFloats.add(new Float(numberStrings[i]));
}
return myFloats;
}
If you want the parseAll() method to return null if there are any errors (like the original example), you'd put the try/catch on the outside like this:
public static ArrayList parseAll1(String[] numberStrings){
ArrayList myFloats = new ArrayList();
try{
for(int i = 0; i < numberStrings.length; i++){
myFloats.add(new Float(numberStrings[i]));
}
} catch (NumberFormatException nfe){
//fail on any error
return null;
}
return myFloats;
}
In reality, you should probably return an error here instead of null, and generally I don't like having multiple returns, but you get the idea.
On the other hand, if you want it to just ignore the problems, and parse whatever Strings it can, you'd put the try/catch on the inside of the loop like this:
public static ArrayList parseAll2(String[] numberStrings){
ArrayList myFloats = new ArrayList();
for(int i = 0; i < numberStrings.length; i++){
try{
myFloats.add(new Float(numberStrings[i]));
} catch (NumberFormatException nfe){
//don't add just this one
}
}
return myFloats;
}
As already mentioned, the performance is the same. However, user experience isn't necessarily identical. In the first case, you'll fail fast (i.e. after the first error), however if you put the try/catch block inside the loop, you can capture all the errors that would be created for a given call to the method. When parsing an array of values from strings where you expect some formatting errors, there are definitely cases where you'd like to be able to present all the errors to the user so that they don't need to try and fix them one by one.
If its an all-or-nothing fail, then the first format makes sense. If you want to be able to process/return all the non-failing elements, you need to use the second form. Those would be my basic criteria for choosing between the methods. Personally, if it is all-or-nothing, I wouldn't use the second form.
As long as you are aware of what you need to accomplish in the loop you could put the try catch outside the loop. But it is important to understand that the loop will then end as soon as the exception occurs and that may not always be what you want. This is actually a very common error in Java based software. People need to process a number of items, such as emptying a queue, and falsely rely on an outer try/catch statement handling all possible exceptions. They could also be handling only a specific exception inside the loop and not expect any other exception to occur.
Then if an exception occurs that is not handled inside the loop then the loop will be "preemted", it ends possibly prematurely and the outer catch statement handles the exception.
If the loop had as its role in life to empty a queue then that loop very likely could end before that queue was really emptied. Very common fault.
My perspective would be try/catch blocks are necessary to insure proper exception handling, but creating such blocks has performance implications. Since, Loops contain intensive repetitive computations, it is not recommended to put try/catch blocks inside loops. Additionally, it seems where this condition occurs, it is often "Exception" or "RuntimeException" which is caught. RuntimeException being caught in code should be avoided. Again, if if you work in a big company it's essential to log that exception properly, or stop runtime exception to happen. Whole point of this description is PLEASE AVOID USING TRY-CATCH BLOCKS IN LOOPS
In your examples there is no functional difference. I find your first example more readable.
You should prefer the outer version over the inner version. This is just a specific version of the rule, move anything outside the loop that you can move outside the loop. Depending on the IL compiler and JIT compiler your two versions may or may not end up with different performance characteristics.
On another note you should probably look at float.TryParse or Convert.ToFloat.
If you put the try/catch inside the loop, you'll keep looping after an exception. If you put it outside the loop you'll stop as soon as an exception is thrown.
I's like to add my own 0.02c about two competing considerations when looking at the general problem of where to position exception handling:
The "wider" the responsibility of the try-catch block (i.e. outside the loop in your case) means that when changing the code at some later point, you may mistakenly add a line which is handled by your existing catch block; possibly unintentionally. In your case, this is less likely because you are explicitly catching a NumberFormatException
The "narrower" the responsibility of the try-catch block, the more difficult refactoring becomes. Particularly when (as in your case) you are executing a "non-local" instruction from within the catch block (the return null statement).
If you want to catch Exception for each iteration, or check at what iteration Exception is thrown and catch every Exceptions in an iteration, place try...catch inside the loop. This will not break the loop if Exception occurs and you can catch every Exception in each iteration throughout the loop.
If you want to break the loop and examine the Exception whenever thrown, use try...catch out of the loop. This will break the loop and execute statements after catch (if any).
It all depends on your need. I prefer using try...catch inside the loop while deploying as, if Exception occurs, the results aren't ambiguous and loop will not break and execute completely.
setting up a special stack frame for the try/catch adds additional overhead, but the JVM may be able to detect the fact that you're returning and optimize this away.
depending on the number of iterations, performance difference will likely be negligible.
However i agree with the others that having it outside the loop make the loop body look cleaner.
If there's a chance that you'll ever want to continue on with the processing rather than exit if there an invalid number, then you would want the code to be inside the loop.
If it's inside, then you'll gain the overhead of the try/catch structure N times, as opposed to just the once on the outside.
Every time a Try/Catch structure is called it adds overhead to the execution of the method. Just the little bit of memory & processor ticks needed to deal with the structure. If you're running a loop 100 times, and for hypothetical sake, let's say the cost is 1 tick per try/catch call, then having the Try/Catch inside the loop costs you 100 ticks, as opposed to only 1 tick if it's outside of the loop.
The whole point of exceptions is to encourage the first style: letting the error handling be consolidated and handled once, not immediately at every possible error site.
put it inside. You can keep processing (if you want) or you can throw a helpful exception that tells the client the value of myString and the index of the array containing the bad value. I think NumberFormatException will already tell you the bad value but the principle is to place all the helpful data in the exceptions that you throw. Think about what would be interesting to you in the debugger at this point in the program.
Consider:
try {
// parse
} catch (NumberFormatException nfe){
throw new RuntimeException("Could not parse as a Float: [" + myString +
"] found at index: " + i, nfe);
}
In the time of need you will really appreciate an exception like this with as much information in it as possible.
That depends on the failure handling. If you just want to skip the error elements, try inside:
for(int i = 0; i < max; i++) {
String myString = ...;
try {
float myNum = Float.parseFloat(myString);
myFloats[i] = myNum;
} catch (NumberFormatException ex) {
--i;
}
}
In any other case i would prefer the try outside. The code is more readable, it is more clean. Maybe it would be better to throw an IllegalArgumentException in the error case instead if returning null.
I'll put my $0.02 in. Sometimes you wind up needing to add a "finally" later on in your code (because who ever writes their code perfectly the first time?). In those cases, suddenly it makes more sense to have the try/catch outside the loop. For example:
try {
for(int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
dbConnection.update("MY_FLOATS","INDEX",i,"VALUE",myNum);
}
} catch (NumberFormatException ex) {
return null;
} finally {
dbConnection.release(); // Always release DB connection, even if transaction fails.
}
Because if you get an error, or not, you only want to release your database connection (or pick your favorite type of other resource...) once.
Another aspect not mentioned in the above is the fact that every try-catch has some impact on the stack, which can have implications for recursive methods.
If method "outer()" calls method "inner()" (which may call itself recursively), try to locate the try-catch in method "outer()" if possible. A simple "stack crash" example we use in a performance class fails at about 6,400 frames when the try-catch is in the inner method, and at about 11,600 when it is in the outer method.
In the real world, this can be an issue if you're using the Composite pattern and have large, complex nested structures.

Categories

Resources