How to make java compiler ignore errors/warnings - java

So I have the following bit of code:
public static Image getImage(String filepath, Class cl) {
try {
return ImageIO.read(cl.getResource(filepath));
}
catch (IOException e) {
e.printStackTrace();
}
return null; // Will never execute
}
It's a basic try-catch block. If I am unable to read the image and return it, I immediately go into my catch block. However, because my return is within the scope of the try block and not the entire function, my compiler issues an error when I try to compile and run because it sees that it's possible that I never hit a return statement. Therefore, I've added the return null; line to suppress this warning, but I'd rather have a neater way of doing this without putting code that will never run. I've tried adding
#SuppressWarnings("all")
To my code, but it still gives me an error. Any ideas? I feel like there should be a way to tell the compiler to ignore errors like this.
Also, if it is of any use, I am using IntelliJ as my IDE.

I would suggest what #LuCio eagerly in the comments tried to say. Just don't catch the Exception and pass it upwards:
public static Image getImage(String filePath, Class<?> clazz) throws IOException {
return ImageIO.read(clazz.getResource(filePath));
}
That way you have created an easy helper method. If you would return null, you'd have to document that in JavaDoc and every caller will have to use a not-null assertion logic to then throw an error if it is null.
A try catch block does the same. So instead of passing null upwards you just propagate the exception upwards. You somewhere said that you want to assign the Image to a static field, so you can do that easily like this:
static {
try {
MY_IMAGE = getImage("somepath", MyClass.class);
} catch(IOException e){
throw new IOError(e); // will kill the Vm with an error
}
}
But maybe somewhere you have another action. Than to just kill the VM. Maybe use a default image:
final Image image;
try {
image = getImage("somepath", MyClass.class);
} catch(IOException e){
e.printStacktrace();
image = new SomeDefaultImage();
}
// do something with image
Which all in all is the way to go. You can't have a helper method to decide what to do when it fails. That should always be done by the calling code.

Ok so, I believe I was confusing the purpose of the catch block. Thank you to #Ben and #Zephyr and everybody else for your help. I will be amending my code to:
public static Image getImage(String filepath, Class cl) {
try {
return ImageIO.read(cl.getResource("hello"));
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
throw new IOError(e);
}
}
Edit: After some more discussions, and looking through other options other people have posted, I have updated my code above, which satisfies the compiler. Note that replacing the line
throw new IOError(e)
with
System.exit(0);
does not fix the error because, as far as I know, the compiler cannot tell at compile time whether the program would end. It would've been helpful to have a way of suppressing the warning, since we know that at runtime the program will always (or practically always) end, but alas #SuppressWarnings is of no use.

Related

Java: Wrap code with a try catch block function?

I have several functions where I am casting an object to an explicit type.
The problem is, when this object is created, the type may not match the type I am casting to. Somewhere along the line there are some conversions that take place. However, it is possible the code never reaches these conversions. The fact that it doesn't is not an issue.
So when the code reaches the point where the casting will occur, all I need to do is put the part into a try catch block. In fact I don't even need to handle the exception in any special way.
But I have a lot of these functions. I would like to know if there is some way to wrap lines of code with a try catch block without actually writing out the try catch block. If I can call some function some how that will do it automatically.
try
{
// cast something
}
catch( ClassCastException e )
{
}
Instead I want to call a method that will put the try catch block around // cast something. Is there any way to do something like this?
Note: I don't do anything when I catch the ClassCastException. It is okay if I can't cast the object correctly, but I need to catch the exception so the code execution won't jump to some other place.
You can write a method like this to do the casting for you while ignoring any ClassCastException.
public static <I, O> O cast(I input, Class<O> outClass) {
try {
return outClass.cast(input);
} catch (ClassCastException e) {
return null;
}
}
You can use it like this:
Number n = new Integer(1);
Integer i = cast(n, Integer.class);
But you can also improve the code to avoid exceptions:
public static <I, O> O cast(I input, Class<O> outClass) {
if(outClass.isAssignableFrom(input.getClass())) {
return outClass.cast(input);
} else {
return null;
}
}
Not really, because this doesn't make any sense. If there's nothing you need to do when you catch the exception, then don't call the operation at all and delete all the code after. If it doesn't matter whether the operation succeeds or fails then don't call it in the first place.
More seriously - ahem, that was serious - you can not catch the exception and let the caller deal with it.
Try to create a common method that does this casting for you
private MyTypeOfObject cast (Object obj) {
try {
// your casting code
return newObj;
} catch (ClassCastException ee) {
// log and ignore
return null; // ????
}
}
There's nothing that I know of to do this (other than what #Scary_Wombat said) but if I were in your shoes I would just write a simple code generator to handle these repetitive/boilerplate cases using some templating engine like Freemarker or something more advanced like Antlr. There are tutorials about the place on each.

Removing dead code leads to error

I'm using Eclipse 4.3 Kepler (actually STS 3.6.1).
I ran into some code:
private String someMethod(String myParam) {
try {
MyInterface myVar = (MyInterface) domeSomething(myParam);
if (myVar != null) {
return myVar.methodThatReturnsString();
}
} catch (Exception e) {
return "";
}
return ""; // eclipse marks this as dead code
}
(As you'd expect, the doSomething() method throws some exception, and it returns an interface more general than MyInterface.)
Eclipse underlines the last return statement as dead code, and if I remove it as the quickfix suggests, I and up with the "This method should return a result of type String" error.
Why is the last return statement dead code? Is it because of the class cast? Say that doSomething() could return null, if you cast it, would that throw a class cast exception?
And, why does Eclipse suggest that I fix the error with something that leads to a dead code warning? Is it because Eclipse can't predict this?
There's no dead code in your posted code. The only problem I can see is here:
if (myVar != null) {
return myVar;
}
You're returning a MyInterface when you should return a String. The compiler will complain about it and it's right.
Also, as a better alternative, you should not directly return inside the try or catch block, instead design a single place after this block to return the result. This will make your code avoid any dead code compiler error. Your could should look like:
private String someMethod(String myParam) {
String result = "";
try {
MyInterface myVar = (MyInterface) domeSomething(myParam);
if (myVar != null) {
result = myVar.methodThatReturnsString();
}
} catch (Exception e) {
//handle the exception
//basic handling shown
System.out.println("Warning. There was a problem executing someMethod:");
e.printStacktrace();
}
return result;
}
You are most likely using Eclipse's annotation org.eclipse.jdt.annotation.NonNull on the method domeSomething.
In that case, the Eclipse compiler knows, that the variable does not refer to null and thus the code will either return the variable (BTW: This is another compiler error, as the variable is not of type String) or throw an exception which will return the empty string. The last line is then indeed dead code. Hence, the warning.
However, removing that last line leads to code that does not comply with the JLS. Hence, the compiler error.

Can an object dynamically loaded with possible exceptions be declared as final?

At first I was going to make the question solely about the Image class, but I wanted to make it as broadly applicable as possible.
Basically, here's the scenario. I'm making a file for GUI constants, and in this file I'd like to have final variables for each of the Images I'm using. So my fields are declared like this UP_ARROW is:
public static final Image UP_ARROW;
Then I try to load them when the ImageIO API, like so:
static {
UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}
Unfortunately, this isn't valid, compilable code, because it explicitly throws IOException, which I have to deal with. So I modify it and surround it with a try/catch:
static {
try {
UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}
catch(IOException ioe) {
//TODO
}
}
Now I get a different compiler error. This time it says there's a possibility that the field may not have been initialized. Okay, that makes sense. Thank you for pointing that out to me, compiler. That seems like an easy fix:
static {
try {
UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}
catch(IOException ioe) {
UP_ARROW = null;
}
}
Now, no matter what, the UP_ARROW must be populated with either my image or null. I'm prepared to declare victory and move on. But now I get another, unexpected compiler error:
... Foiled again, compiler!
Hence the question: is there any way to get around this, such that I can dynamically load final fields at runtime? Or do I declare defeat and simply make the Images non-final?
Also, an explanation as to why the compiler won't allow this would be helpful as well. As I understand it, based on the code above, the UP_ARROW object could not have been assigned before reaching the catch{} block, because that's what must have thrown the exception. So if the try{} executes successfully, only one assignment takes place. If it does not execute successfully, still only one assignment take place. How is that not valid?
The following should do it:
static {
Image up_arrow = null;
try {
up_arrow = ImageIO.read(new File("img/upArrow.png"));
}
catch(IOException ioe) {
// log the error?
}
UP_ARROW = up_arrow;
}
It might make sense to enclose the final assignment in a finally block .
NPE's answer is good, but I think this one is (based off his and) better:
public enum Arrows {
UP ("img/upArrow.png"),
DOWN ("img/downArrow.png"),
LEFT ("img/leftArrow.png"),
RIGHT ("img/rightArrow.png");
public final Image myImage;
private Arrows(String fileName) {
Image tempImage;
try {
tempImage = ImageIO.read(new File(fileName));
} catch (IOException e) {
tempImage = null;
}
myImage = tempImage;
}
}
This solves your problem and gives you all the advantages of an enum over static final variables.

How to avoid many try catch blocks in java

I'm very new to java and the idea of try catch blocks to handle exceptions.
This roughly what I'm ending up with, and there simply has to be a better way:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
There are more try catch blocks embedded in the same way, so that at the end, there is just a lump of catch blocks. How else should exceptions be handled, Eclipse keeps asking my to either surround with a try catch block or "Add throws declaration".
Sometimes I want to catch certain exceptions, for example if it can't find an entity, I want to print something like "Entity not found", and if the JSON string can't be parsed into an object, I want to print something like "Can't parse JSON".
(I'm used to objective-c where the are delegate methods for failure, or the method returns null and you have passed a pointer to [a pointer to] an NSError object, which will have been "filled", Is there somewhere to learn about try-catch?)
If all you're doing is catching them and printing the stack trace regardless of the exception type, you can just wrap the code in one large try/catch block. To save many "catches", you can catch java.lang.Throwable which is the interface that all exceptions implement. If not, you can have a catch for every type of checked exception the code you're calling throws, and handle them specifically.
Eclipse keeps asking you to do so because Java code will not compile if the checked exceptions are not caught, or declared to be thrown by the caller.
+Adding this comment to the answer (Thanks, Paul Tomblin):
In production quality apps you'd be logging the trace, adding some logic where you're handling the exception in a right way, taking an alternate flow, and/or re-wrapping it in another exception and throwing it, etc. It all depends on the particular problem you're trying to solve.
The idea of exception handling is that you can handle errors at points in your program flow where you can deal with them meaningfully. Rather than checking every function's return value like in C, where most of the time you can't do anything sensible other than passing the error further up, you install a try/catch block at sensible points in your program:
Basically, whenever there is a point where you can react meaningfully to an error, then catch that error, and pass everything else on. That way, error handling is only invoked when there is a plausible recovery from the error.
For example, worst case if any error stops your program from executing meaningfully, then you might almost not catch anything at all and just let the OS handle the situation (well, perhaps one single try/catch to produce a friendly error message).
Example (in C++, sorry, I'm can't type Java blind):
int main()
{
try {
while (masterloop()) { }
catch (...) {
LOG("Fatal program error, terminating!"); // nothing else we can do!
}
}
/* lots of program logic */
void process_image()
{
try {
Image im = load_image_from_disk();
/* ... */
}
catch (const OutOfMemoryExc & e) {
LOG("Not enough memory to process the image.");
return;
}
catch (const DataErrorExc & e) {
LOG("Could not read the image data.");
return;
}
catch (...) {
throw; // pass everything else along
}
}
In this example, we may try to process an image and fail for some anticipable reasons (out of memory, or failure to read the image). In that case we just return without doing work and let the program continue gracefully. All other errors are propagated up to a higher point. Most importantly, we do not need to litter the actual image processing function with error checks and responses all the time, it suffices for any code there to throw one of our two good exceptions and not worry any further.
Moral: If you have try/catch blocks absolutely everywhere, you're doing it wrong.
I know there's a lot of answers here, and they do a good job of covering how to structure the try/catch blocks. However, I'm thinking one of the things bothering you is the significant... indentation and code growth (... because I know it's not the indentation or amount of code, but the implied complexity by wrapping it and shifting it over and growing longer and longer between the opening try and enclosing catch, and I can't put a word to that apprehension).
The way to get around this is to refactor into functions the distinct bits in the code. I know it's a simplistic answer, but it's a good way to isolate individual tasks and keep the error handling fairly local to the code that requires it without padding things out vertically and horizontally with nested try/catch blocks.
You can make these methods private as they are intended for internal use only, presumably.
private Integer getDatastoreACount() {
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
return (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
// expects an Integer return, so need to deal with this
// but for simplicity I'm just simply recycling 'e'
throw e;
}
}
public void parseJSON(String jsonString) {
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
Integer dsACount = getDatastoreACount();
//etc etc
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
}
You can catch multiple exceptions in the same try e.g.
try{
xyz;
}catch(NullPointerException npx){
npx.getMessage();
}catch(ArrayOutOfBoundsException ax){
ax.getMessage();
}
Also, by declaring the Exception as throws in your method signatures you can pass the Exception up the stack.
If you're just doing something like this:
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
} catch (Exception2 e2) {reaction to e2}
You can do everything in one try-block:
try {
do smth
do smth more
...
}
catch (Exception1 e1) {reaction to e1}
catch (Exception2 e2) {reaction to e2}
You can also break this down to one catch block if you're just printing the exception:
try {
do smth
do smth more
...
}
catch (Exception e) {e.printStackTrace();}
But this doesn't if you want to do somthing more, even if e1 is thrown, like:
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
do smth even if e1 was thrown
} catch (Exception2 e2) {reaction to e2}
The last example can't be written shorter.
If you have a block of code in which more than one type of exception may be thrown, you can declare two separate catch blocks:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
//..etc.. as many catch blocks as needed
Alternatively, if you don't care about the exact type of the exception, you can have onyl one catch block which catches Exception (or maybe Throwable; I can't remember exactly what the superclass of exceptions is in Java).
Another point I will make now is that you might not have the most modular code. Remember, code that does one thing well makes for good, modular code. If you find that you have many nested black (whether try/catch blocks, if/else blocks, etc.) you may want to check if some of the code can be extracted into its own method. This may also make your code look better when many exceptions must be handled.
First, from a design perspective, catching and printing exceptions is not a good thing. Something went wrong, and your code just keeps going in the same way as if it went right. That is not usually correct. So: perhaps your method needs to throw these exceptions instead of catching them. Perhaps only the caller is in a position to decide what happens if something fails like this.
But otherwise, the only advice I can offer to clean up how the code looks, syntactically, is to tell you that you can write:
try {
...
} catch (...) {
...
} catch (...) {
...
}
You can also catch for a broader exception class like Exception and just write one catch block but this is bad design. In Java 7, you will be able to catch for several exception types in one block.
You should use try/catch blocks if you have a way to recover from the exception, for example if you want to check if a string is a valid integer, you can write a method (this is a lame method, but just to show the idea):
public boolean isInteger(String str) {
try {
new Integer(str);
}
catch(NumberFormatException e) {
return false;
}
return true;
}
If you don't have a way to recover from the exception and all you do is to print the stack trace, it is suggested to add throws declaration (as eclipse suggest) to the method, and let the caller handle the exception (or throw it to its caller).
If you want to handle some exceptions and throw some other, you can do it as well.
I like to box up the call behind a static method, just to keep it tidier. For example, here's my reduced Set Json Value call.
private static boolean setJsonValue(JSONObject j,String key,Object value)
{
try
{
if(value instanceof Integer)
{
// numbers are special. We want them unquoted.
int valueI = (Integer)value;
j.put(key,valueI);
}
else
j.put(key,value);
return true;
}
catch (JSONException e)
{
// do nothing, it turns out
return false;
}
}
...and then I ignore the return values, because I am bad.
Somewhere or other I have a similar Get method, that returns null if it fails. You get the idea.
You have two basic code-style choices here (that don't involve changing method signatures)
Method1: Put everything in the one try catch and have multiple catch blocks, like this:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
Method 2: Break up your code into sections that each have one catch, like this:
String qURL = null;
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
Method 2 is the recommended one, as it makes it obvious which lines are throwing which exceptions and generally segments the code into natural processing blocks.
Create another exception and put it below or above of the other exception. Depends on the context of your application.

What is the proper way to handle a NumberFormatException when it is expected?

I'm running into this situation where I need to parse a String into an int and I don't know what to do with the NumberFormatException. The compiler doesn't complain when I don't catch it, but I just want to make sure that I'm handling this situation properly.
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
i = 0;
}
return i;
}
I want to just simplify my code like this. The compiler doesn't have a problem with it, but the thread dies on the NumberFormatException.
private int getCurrentPieceAsInt() {
int i = 0;
i = Integer.parseInt(this.getCurrentPiece());
return i;
}
Google CodePro wants me to log the exception in some way, and I agree that this is best practice.
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
i = 0;
e.printStackTrace();
}
return i;
}
I want this method to return 0 when the current piece is not a number or cannot be parsed. When I don't catch the NumberFormatException explicitly, does it not assign the variable i? Or is there some default value that Integer.parseInt() returns?
General style says that if I catch an exception, I should log it somewhere. I don't want to log it. It's normal operation for this exception to be thrown sometimes, which also doesn't sit well with me. I cannot find a function, however, which will tell me if Integer.parseInt() will throw an exception. So my only course of action seems to be to just call it and catch the exception.
The javadoc for parseInt doesn't help much.
Here are the specific questions I'd like to know:
Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
Sadly, no. At least not in the core Java API. It's easy to write one, however - just modify the code below.
If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
If you do not catch the exception then the stack will unwind until it hits a catch block that will handle it, or it will unwind completely and halt the thread. The variable will, in fact, not be assigned but this is not exactly what you want.
Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
There may be a way to tell CodePro to ignore this particular warning. Certainly with tools like FindBugs and Checkstyle you can turn off warnings in specific locations. (EDIT: #Andy has pointed out how to do this.)
I suspect what you want is something like the Commons lang package mentioned by #daveb. It's pretty easy to write such a function:
int parseWithDefault(String s, int def) {
try {
return Integer.parseInt(s);
}
catch (NumberFormatException e) {
// It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
return def;
}
}
There is NumberUtils.toInt(String, int) in commons lang which will do exactly what you want.
NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42
* Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
Yes, you can locally disable a CodePro audit rule for one line of code:
http://code.google.com/javadevtools/codepro/doc/features/audit/locally_disabling_audit_rules.html
That said, it is not necessarily required to include diagnostic logging in every exception catch block. Sometimes, the best action is to take a default course. Sometime it's to interact with the user. It depends.
Create your own convenience method for now and future use:
public static int parseInt(final /*#Nullable*/ String s, final int valueIfInvalid) {
try {
if (s == null) {
return valueIfInvalid;
} else {
return Integer.parseInt(s);
}
} catch (final NumberFormatException ex) {
return valueIfInvalid;
}
}
Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
Not that I'm aware of. Keep in mind that if there were, you likely end up parsing the value twice (once to validate and once to parse it). I understand you want to avoid the exception, but in this case, this is catching the exception is the standard idiom in Java and it doesn't provide another (at least that I know of).
If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
You must catch the exception (even if it does nothing) or it will escape the block and throw up through the stack.
Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
I don't know of any. I would use the above convenience method (I have something similar in a small collection of general utilities I have available for use on my all projects).
I wouldn't log it if its truly a normal condition that you are handling. I'm not familiiar with Google CodePro, but I would hope there is a way to suppress the warning, e.g. some sort of #SuppressWarnings("xxx") annotation/keyword.
Edit: I wanted to point out these comments in the comments below
This approach still doesn't handle the exception. It's bad form to catch an exception and do nothing with it. This is why I am looking for a better solution
.
... The exception (the situation) is being handled by returning the indicated valueIfInvalid. The "bad form" you are referring to the poor practice of blindly and unthinkingly writing empty catch blocks and never going back to truly consider and address the case. If the exception situation is considered and does the right thing for the situation (even if the right thing is to do nothing), then you've "handled" the exception.
You should catch the Exception as you are doing. It is annoying, but the best approach.
There is no Java API method that will return 0 when the string is not a valid int.
When the string is not an int, an exception will be thrown so your int variable will not be set unless you catch the exception as you are doing.
If its not clear how you should handle it from the getter, you shouldn't catch it and let the caller deal with it instead. If you know how it should be handled you should just do that. Logging it may not be required or very useful in this case.
Logging an exception is more useful if you don't know how to handle the exception and you are leaving it to the person reading the logs.
Your first code block is correct. i won't be implicitly converted to 0 when an exception occurs and you have to catch that exception. Setting i to 0 inside catch is correct; although you can simply replace i = 0; with return 0;. You cannot avoid exception handling in this case.
To clarify, you can use this:
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
// log that an exception occured if it's needed
return 0;
}
return i;
}
As others have mentioned, there is not a built-in core Java API method you can call to validate an integer, but you can use the Character class to validate your input without using exception handling. For example:
package com.example.parseint;
public class ValidateIntExample {
public static boolean isInteger(String s) {
if (s == null) {
return false;
}
s = s.trim();
if (s.length() == 0) {
return false;
}
int start = 0;
if (s.charAt(0) == '-') { // handle negative numbers
if (s.length() == 1) {
return false;
}
else {
start = 1;
}
}
for (int i = start; i < s.length(); i++) {
if (! Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
}
In fact, parseInt itself uses Character.isDigit internally, which you can verify in the JRE source code. (Sorry, I would have included the parseInt method here, but I'm not sure if I'm allowed under the license terms.) If you're using Eclipse and you have the JRE source code attached to your project, you can right-click on the method Integer.parseInt in your code and click Open Declaration.

Categories

Resources