How to avoid try-catch when validating text input - java

While working on a code, I was wondering if I could avoid try n catch and used something else. For example, if i have a value(from console) of type double and if user enters a string or something else then there should be a prompt to re-enter the value.
I know this can be done very easily using try-n-catch but how can we do it without it, is there any way out?
Please give an example if possible.

Sadly, the JDK lacks the TryParse method that some other libraries provide. I wouldn't be surprised to find something in Apache Commons or Guava that does it.
Alternately, you might use a Scanner and use its hasNextDouble to do the check.
If you're asking how to avoid dealing with exceptions in general: Don't try. Exceptions are a powerful way of handling exceptional conditions in programs, and the "handle-or-declare" provided by checked exceptions (e.g., your code must handle the exception, or declare that it doesn't) is very useful.
But there are some use-cases, like your example, where you might well want to avoid an exception being thrown because, after all, a user entering invalid input isn't an exceptional condition, it's an all-too-common one. :-)

Throw Exceptions are less robust but a good way to deal avoiding with try/catch statements.
import java.io.*;
public class UsingThrows {
public static void main(String args[]) throws FileNotFoundException {
FileInputStream fis = new FileInputStream("def.txt");
System.out.println("OK 1");
}
}

Related

Java - Write one method to handle all exceptions

im trying to handle exceptions on my code and at the same time without repeating it. I have lots of method on the "System" Class and i would prefer not to write "Try Catch" in all of them as i believe that there is some other way not to repeat it.
Any Ideas?
The exception that i want to handle is (InputMismatchException).
Edit: More info just in case you need it.
I have several methods where the User needs to input 'Int'(using Scanner), thats what i need to handle.
Using Java 7 you can do it.
Refer
Can I catch multiple Java exceptions in the same catch clause?
Working with Java SE 7 Exception Changes
I don't generally recommend this: Just make all your methods to throw exception and treat all the exceptions at a upper level in one place. This is good only is for some tests or when you want to rapid develop something and shouldn't be the normal approach.
You can find more here:
https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html
Also some rules regarding how should you do it:
Throws or try+catch
This is a different approach you want to try, that does not deal with Exceptions implicitly.
As mentioned in your comments you're taking input from the user through the Scanner class. Since the Scanner allows the user to type in any value they desire and you only want to deal with Integers, you probably want to (or you're using already) the Scanner.nextInt() method. Tutorial here.
If you just need to handle the InputMismatchException, this question has an answer that handles all that exception in one place.
Alternatively, as this question explores, you could do away with having to deal with Exceptions by just always asking the user for an int until the user properly enters an integer, modified below:
Scanner sc = new Scanner(System.in); //your scanner instance
System.out.print("Enter a number.");
while (!sc.hasNextInt()) {
System.out.println("Enter a whole number");
sc.next();
}
int x = sc.nextInt();
What the while loop in there does is always repeat whenever the scanner does not have a next integer, hence the !sc.hasNextInt() condition, and prompt the user for another number with the message and the sc.next(), which is a method that waits for the user to input again.
Once the user enters a number, the hasNextInt() method will return a true, which makes the while loop condition false (since we did a !hasNextInt() ) where ! gives the other Boolean value, and the assigned x will always be an int, hence avoiding exception handling.
This is good because you don't have to deal with a ton of exceptions and try-catch blocks, and avoid having to do the discouraged methods as others have mentioned, and I'm presuming this is for a simple program or some assignment, avoiding the extra complexity.
However if you need more advanced error handling exceptions are definitely something you should look into, so you're on the right track of thought.
It's not a good idea to have one god class that handles all exceptions. Usually each exception is a unique situation that should be handled separately.
But if you still want to, you could add throws declaration to each of your method and then in one start point catch them all.

Throwing an IllegalArgumentException isn't working

So, for a homework assignment, our professor wants us to try inserting an integer into an array of Strings:
public boolean addPerson(V person, int number)throws IllegalArgumentException{
if(numEntries < people.length){
people[numEntries] = person;
phones[numEntries] = number;
numEntries++;
return true;
}
return false;
}
public static void main(String[] args){
PhoneBook<String> names = new PhoneBook<String>();
PhoneBook<Integer> ssn = new PhoneBook<Integer>();
names.addPerson("john", 1235681213);
ssn.addPerson(123324567, 2048);
Integer soc = 132546789;
try{
names.addPerson(soc, 1996);
}
catch(IllegalArgumentException e){
System.out.println("You cannot enter a Social Security Number "
+ "into the Name phone book!");
}
But, this isn't working, and I still get the same error as without the try-catch. Any idea what I'm doing wrong?
EDIT
Sorry guys, I probably should've included the code for the addPerson method. I don't really know how to deal with exceptions yet.
What your professor likely wants you to observe is a compilation error. An array's type is fixed at instantation time, and will not change. The array will only ever accept whatever type it has been declared to accept, and nothing else.
Minor rant about exceptions to follow from here.
Let's have a quick chat about checked and unchecked exceptions. There is a difference between these two, and mixing them up can be painful at times.
Let's start with the checked exceptions. These are the exceptions that you must either explicitly catch yourself, or declare them to be thrown. Things along those lines are IOException, FileNotFoundException*, and a few others - pretty much anything that extends from the Exception class.
Java is telling you that you have the ability to recover from this error, and you as a good developer should ensure that your program does.
There are also unchecked exceptions; anything that extends RuntimeException or Error. These do not need to be declared to be thrown, as they occur during the runtime of the application, and there's really no guarantee if the program should recover from this error. An example of this would be ArithmeticException; should your application really recover if it tried to divide by zero? What state would it be in?
There are also some you really shouldn't be catching at all - what would you return to if you managed to catch an OutOfMemoryError? There isn't much you really can do at that point!
Now, to your code: you've declared an unchecked exception to be thrown. That's valid syntax, but Java isn't going to just arbitrarily throw the exception for you, because there isn't anything in that block of code that would just throw it. At worst, you could get an ArrayIndexOutOfBoundsException, but that's no IllegalArgumentException.
In order to actually throw that unchecked exception, you'd need to explicitly throw it:
throw new IllegalArgumentException();
...and you'd also need a good reason to do so. Exceptions are expensive.
*: I realize that FileNotFoundException is-an IOException. It's still checked.

When to use an exception instead of a boolean

Let say you have a method that checks if the argument (Answer) is correct and check if the question already have answers in the list that is also correct:
public void addAnswer(Answer answer) {
if (answer.isCorrect()) {
...
}
}
However, I only want one answer to be correct in the list. I have multiple options. I could throw an exception, I could ignore it, I could return some boolean value from the addAnswer that tells me if the operation was ok or not. How are you supposed to think in such scenarios?
The rule is pretty simple: Use exceptions on exceptional, erroneous, unpredicted failures. Don't use exceptions when you expect something to happen or when something happens really often.
In your case it's not an error or something truly rare that an answer is not correct. It's part of your business logic. You can throw an exception, but only as part of some validation (assertion) if you expect an answer at given point to always be correct and suddenly it's not (precondition failure).
And of course if some failure occurs while checking correctness (database connection lost, wrong array index) exception are desired.
This entirely depends on what you want to achieve. Should the caller of your method already have made sure that it doesn't add two correct answers? Is it a sign of a programming error if that happens? Then throw an exception, but definitely an unchecked exception.
If your method's purpose is to relieve the caller from enforcing the one-true-answer invariant (I doubt that, though), then you can just arrange to signal via a boolean return value, which makes it only an optional information channel for the caller.
If there is no way to know in advance whether there are other correct answers—for example, the answers are added concurrently from several threads or even processes (via a database)—then it would be meaningful to throw a checked exception.
Bottom line: there is no one-size-fits-all best practice, but there is a best practice for every scenario you want to accomplish.
The exception police will be down on you like a ton of bricks, and me for this answer, with statements like "don't use exceptions for flow control" and "don't use exceptions for normal conditions".
The trouble with the first statement is that exceptions are a form of flow control. This makes the argument self-contradictory, and therefore invalid.
The trouble with the second statement is that it seems to inevitably go along with endlessly redefining exceptional conditions as normal. You will find examples in this very site: for example, a lively discussion where the police insisted that EOF was 'normal' and therefore that EOFException shouldn't be caught, despite the existence of dozens of Java APIs that don't give you any choice in the matter. Travel far enough down this path and you can end up with nothing that is exceptional whatsoever, and therefore no occasion to use them at all.
These are not logical arguments. These are unexamined dogmas.
The original and real point, back in about 1989 when it was first formulated, was that you shouldn't throw exceptions to yourself, to be handled in the same method: in other words, don't treat it as a GOTO. This principle continues to have validity.
The point about checked exceptions is that you force the caller to do something about handling them. If you believe, on your own analysis, that this is what you want, use an exception. Or, if you are using an API that forces you to catch them, catch them, at the appropriate level (whatever that is: left as an exercise for the reader).
In other words, like most things in the real world, it is up to your discretion and judgment. The feature is there to be used, or abused, like anything else.
#Exception police: you will find me in the telephone book. But be prepared for an argument.
An exception thrown from a method enforces the callers to take some action in the anticipation of the exception occurring for some inputs. A return value doesn't enforce the same and so it is up to the caller to capture it and take some action.
If you want the callers to handle the scenario to take some corrective action, then you should throw a checked exception (sub class of java.lang.Exception).
The problem here is that your API is error prone. I'd use the following scheme instead:
public class Question {
private List<Answer> answers;
private int mCorrect;
// you may want a List implementation without duplicates
public void setAnswers(List<Answer> answers, int correct) {
this.answers = answers;
// check if int is between bounds
mCorrect = correct;
}
public boolean isCorrect(Answer answer) {
return answers.indexOf(answer) == mCorrect;
}
}
because an Answer by itself is simply a statement, and usually cannot be true of false without being associated to a Question. This API makes it impossible to have zero or more than one correct answers, and forces the user to supply the correct one when he adds answers, so your program is always in a consistent state and simply can't fail.
Before deciding how to signal errors, it's always better to design the API so that errors are less common as possible. With your current implementation, you have to make checks on your side, and the client programmer must check on his side as well. With the suggested design no check is needed, and you'll have correct, concise and fluent code on both sides.
Regarding when to use a boolean and when to use Exceptions, I often see boolean used to mirror the underlying API (mostly low level C-code).
I agree with Tomasz Nurkiewicz's response. I cant comment on it because I'm a new user. I would also recommend that if the addAnswer() method is not always going to add the answer (because they already exists a correct one), name it to suggest this behaviour. "add" is suggest normal collections behaviour.
public boolean submitAnswer(Answer answer); // returns true is answer accepted
Your exact solution may depend on the bigger picture about your application that we dont know about. Maybe you do want to throw an Exception but also make it the responsibility of the caller to check if adding the Answer is valid.
It's all a rich tapestry.
I would implement it in this way:
public class Question {
private int questionId;
private final Set<Answer> options = new HashSet<Answer>();
private final Set<Answer> correctAnswers = new HashSet<Answer>();
public boolean addAnswer(Answer answer) throws WrongAnswerForThisQuestionException {
if(!answer.isValid(questionId)) {
throw new WrongAnswerForThisQuestionException(answer, this);
}
if (answer.isCorrect(questionId)) {
correctAnswers.add(answer);
}
return options.add(answer);
}
}

Try-catch: is this acceptable practice?

We have received Java code from a software supplier. It contains a lot of try-catch blocks with nothing in the catch part. They're all over the place. Example:
try {
spaceBlock.enable(LindsayModel);
} catch (Exception e) {
}
My questions are: Is the above acceptable practice? If so, when? Or should I just go ahead and remove all of these "bogus" try and catch statements?
To me this looks like terrible practice, but I'm not experienced enough in Java to tell for sure. Why catch errors if you're not going to do anything with them? Seems to me, you would only do that if you were confident that an exception would be of absolutely no consequence and you don't care if one occurs. However, this is not really the case in our particular application.
EDIT To give some context: We bought a Java-scriptable product from the supplier. Alongside the product, they provided a large proof-of-concept script tailored to our needs. This script came "free of charge" (though we wouldn't have bought the product if it hadn't come with the script) and it "works". But the script is a real pain to build upon, due to many things that even I as a Java novice recognise as awful practice, one instance being this bogus try-catch business.
This is indeed terrible practice. Especially the catching of Exception rather than something specific gives off a horrible smell - even a NullPointerException will be swallowed. Even if it is assured that a particular thrown exception is of no real consequence, one should always log it at the very least:
try {
// code
}
catch (MyInconsequentialException mie) {
// tune level for this logger in logging config file if this is too spammy
MY_LOGGER.warning("Caught an inconsequential exception.", mie);
}
However it is unlikely an exception is completely meaningless in this situation. I recommend researching exactly what exception(s) the application's code is intending to swallow here, and what they would really mean for the execution.
One important distinction is whether the try/catches are used to swallow checked exceptions. If this is the case, it probably indicates extreme apathy on the programmer's part - somebody just wanted his/her code to compile. At the least, the code should be amended:
try {
// code
}
catch (SpecificCheckedException sce) {
// make sure there is exception logging done farther up
throw new RuntimeException(sce);
}
This will rethrow the exception wrapped in an unchecked RuntimeException, effectively allowing the code to compile. Even this can be considered a bandaid however - best practice for checked exceptions is to handle them on an individual basis, either in the current method or farther up by adding throws SpecificCheckedException to the method signature.
As #Tom Hawtin mentioned, new Error(sce) can be used instead of new RuntimeException(sce) in order to circumvent any additional Exception catches farther up, which makes sense for something that isn't expected to be thrown.
If the try/catch is not being used to swallow checked exceptions, it is equally dangerous and should simply be removed.
Terrible, indeed. Swallowing an exception like this can be dangerous. How will you know if something bad has happened?
I'd feel better if the vendor wrote comments to document and acknowledge it ("We know what we're doing"). I'd feel even better if there was a strategy apparent in the code to deal with the consequences. Wrap it in a RuntimeException and rethrow; set the return value to an appropriate value. Anything!
"All over the place"? Are there multiple try/catch blocks littering the code? Personally, I don't like that idiom. I prefer one per method.
Maybe you should find a new vendor or write your own.
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
}
This looks like unfinished code. If the enable method throws an Exception then it will be caught and swallowed by the code. If it doesn't then it does not make sense to try to catch a non occuring exception.
Check to see the methods and where their signatures are not followed by throws exceptionName, then remove the empty try-catch statements from the places they are called.
You can theoretically put try-catch around any statement. The compiler will not complain about it. It does not make sense though, since this way one may hide real exceptions.
You can see this as a sign of bad code quality. You should probably be prepared to run into problems of different type too.
It's not the best:
It hides evidence of the exception so debugging is harder
It may cause features to fail silently
It suggests that the author might actually have wanted to handle the exception but never got around to it
So, there may be cases where this is OK, such as an exception that really is of no consequence (the case that comes to mind is Python's mkdirs, which throws an exception if the directory already exists), but usually, it's not so great.
Unfortunately you cannot just remove it, because it the try block throws a checked exception then it will have to be declared in the throws clause of the method. The callers of the method will then have to catch it (but not if the callers also have this catch (Exception e) {} abomination).
As an alternative, consider replacing it with
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
Since RuntimeException (and classes that extend it) are unchecked exceptions they do not need to be declared in the throws clause.
What did your contract with the supplier specify? If what they wrote, bad practice and all, meets the spec then they will charge you for a rewrite.
Better to specify a set of tests that will enter many or all of those try-catch blocks and hence fail. If the tests fail you have a better argument to make them fix their terrible code.
Horrible idea on the face of it, totally depends on what you're actually calling. Usually it's done out of laziness or habituated bad practices.
Actually ... not so fast.
There are legitimate cases for ignoring an exception.
Suppose that an exception has happened already, and we're already in a catch(). While in the catch(), we want to make best effort to clean up (which could fail, too). Which exception to return?? The original one, of course. The code looks like this:
try {
something-that-throws();
} catch(Exception e) {
try {
something-else-that-throws();
} catch(Exception e1) {}
throw e;
}
When we really don't care whether an operation succeeds, but (unfortunately) the operation's author throws an exception if a failure occurs.
if (reinitialize) {
try {
FileUtils.forceDelete(sandboxFile); // delete directory if it's there
} catch(Exception e) {}
}
The above saves a rather tortured attempt to see if sandboxFile actually exists before deleting it anyway.

Using Exceptions to validate inputs

I am trying to check whether the value passed by an user is valid constant or not. Here is the code I have written.
enum Media_Delivery {
Streaming, Progressive
}
public class TestMain {
public static void main(String[] args) {
String medi_delivery = "streaming";
try {
Media_Delivery.valueOf("streaming");
} catch (IllegalArgumentException e) {
System.out.print(e);
}
}
}
Now, in above code if the String passed is not withing the listed enum then it throws IllegalArgumentException which is obvious.
But my question is: Is this the proper way to validate? As we are using Java's exception mechanism to validate.
Can someone suggest a better idea or what I have coded above itself is the best option ?
-----EDIT--------
Another case which I wanted to discuss:
public class TestMain {
public static void main(String[] args) {
String inputPassed = "2a";
try {
Integer.parseInt(inputPassed);
} catch (NumberFormatException nfe) {
throw new SomeUserDefinedException("Please enter only numeric values");
}
}
So is this a good idea ? Or there should be our own parsing mechanism?
Exceptions should be used for exceptional conditions; things you don't expect to happen. Validating input isn't very exceptional.
Josh Bloch actually outlines this specifically in his book 'Effective Java' which IMHO is something every Java programmer should have.
EDIT: And this is actually a very good answer to how to approach the problem:
Check valid enum values before using enum
It is usually best practice not to catch or throw unchecked expressions (IllegalArgumentException is a RuntimeException which counts as "unchecked"). See the Java Tutorials - Exceptions for more details. If you can avoid it, try rewriting your code such that a runtime exception is not needed to be caught. This is a controversial issue, but runtime exceptions exist for a reason: they help the programmer identify bugs. If you catch them, then the bug is not being fixed, it is just being avoided. Try using an if-else statement?
According to the API, "the name must match exactly an identifier used to declare an enum constant." I believe this means the parameter is case-sensitive. In addition, the return type of the valueOf method is some type, not void, so you can't have that statement in the try block. try blocks should contain commands or void methods, such as int x = 3; or System.out.println(3); or something.
--------EDIT-------
OP, in response to your comment:
Like others here have said, it depends on what you're trying to accomplish. I assume that since you have the line Media_Delivery.valueOf("streaming"); in the try block, that you're attempting to see whether "streaming" is equal to one of the enum constants? In that case, you wouldn't need an if-else statement, you could simply write
boolean result = medi_delivery.equals(Media_Delivery.Streaming.name()) ||
medi_delivery.equals(Media_Delivery.Progressive.name());
System.out.println(result);
Or even better, if you don't want to have multiple || conditions, try a switch statement that cycles through each enum constant, testing the equality of the given string.
-Chris
PS: on naming convention, since enum constants are implicitly static final, it is common practice to declare them in all caps, such as STREAMING and PROGRESSIVE (the Java Tutorials - Enums).
I'd say it depends.
If input comes from GUI element like combobox or anything, where enum values are the only ones to choose - then your approach is ok. Here different value would really be an exception.
But if you're making console app, or textfiled with possibility to type anything then result different then enum values shouldn't be considered as exception. You should use normal if-else or cases with this approach.
generally: use exceptions only for exceptional cases, and not for something that is really likeable to happen.
There is no single "proper" way to validate, what you have would certainly be the way I would validate, but there are other ways(for instance you could put all the valid string values of the enumeration in a HashSet and then check against that set to see if its valid, that is probably what the valueOf method does anyway)
Now if the above approach is any "better" or not, that too is to be pretty subjective. If you are doing the validations in a loop and want to reject anything that contains invalid data, then the exception approach is probably best. If you want to flag all the inappropriate elements then either approach works.... the HashSet will probably be faster if there is a lot of problematic data as you wont have to generate a lot of new exception objects, but even then the difference in performance will be pretty negligible.

Categories

Resources