My code does some arithmetic to convert a binary input to decimal output. I also made an exception class that extends NumberFormatException to throw an error if the input is not a 1 or 0. What I want is to throw the exception to a JTextField.
private void biTodeciActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String binary;
binary = binaryStringText.getText();
int total = 0;
for(int i = 0; i < binary.length(); i++)
{
if (binary.charAt(i) != '0' && binary.charAt(i) != '1')
{
throw new ParseMethods.BinaryNumberFormatException(binary.charAt(i)+" is not"
+" a valid binary input.");
}
else if(binary.charAt(i) == '1'){
total += Math.pow(2, (binary.length()-1)-i );
}
}
deciOut.setText(""+total);
}
Essentially, what you're trying to do won't work. The BinaryNumberFormatException doesn't declare that it throws any exceptions (and assuming you're using NetBeans), you won't be able to (easily) modify it.
You could wrap all you code in a try-catch block within the method, but that's just, well, kind of messy (IMHO)
Instead, what I might do, is create a class which does the conversation, something like...
public static class BinaryConverter {
public static String toDecimal(String binary) throws BinaryNumberFormatException {
//...
}
// Maybe a toBinary method as well...
}
for example. The toDecimal declares the fact that it will throw a BinaryNumberFormatException (although I think some kind of parse exception would be better)
Then in your action performed method, you could do something like...
private void biTodeciActionPerformed(java.awt.event.ActionEvent evt) {
try {
deciOut.setText(BinaryConverter.toDecimal(binaryStringText.getText()));
} catch (BinaryNumberFormatException exp) {
exp.printStackTrace();
deciOut.setText(exp.getMessage());
}
}
which would allow to deal with the operation been successful and unsuccessful in a more succinct manner.
This makes the code more reusable and easier to manager.
As an idea
Print exception directly into textfield in STRING format
deciOut.setText(""+exp);
Related
What I'm doing
I'm trying to make a cleaner version of nested try catch blocks and I'm solving a very basic exception problem while doing so. I'm making a calculator that will do great things. Before then however, it must take in user inputs as strings and convert them to either floats or integers. I'm doing this by simply calling the in built parseInt and parseFloat functions of java. Right now I'm using a nested try catch block to do this:
String stringToParse = "1.0"
try{Integer.parseInt(stringToParse);}
catch(NumberFormatException n){
try{Float.parseFloat(stringToParse);}
catch(NumberFormatException n){
System.out.println(n)
}
}
Why is that a problem?
This is messy to me and I'd rather have a try block that collects the errors but doesn't immediately go to the catch block, rather it executes the entire try and catches any errors after the try has been executed. I've made a runnable example of this myself that shows what I desire:
String num = "1.0";
int i = 0;
ArrayList<Object> listofResults = new ArrayList<>();
ArrayList<Integer> listOfErrorIndices = new ArrayList<>();
try {
listofResults.add(Integer.parseInt(num));
i++;
listofResults.add(Float.parseFloat(num));
i++;
listofResults.add(Integer.parseInt(num));
} catch (NumberFormatException n) {
listOfErrorIndices.add(i);
}
for (Integer element:listOfErrorIndices) {
System.out.println(element);
//this currently prints out 0 and I want it to print out both 0 and
//2 so that it catches both errors.
}
My idea of how to solve the problem/What I've tried otherwise
My plan is to gather a list of all the NumberFormatException indices (i) thrown in the try. Each time I try to parse the string, an element is added to the resultsList. My goal is to then use this theoretical try catch block to obtain the indices of all the exceptions and then remove them from the resultsList if they threw an error. TLDR; Right now the above code prints out 0 and I want it to print out 0 and 2. Basically, Instead of having nested try catch blocks I use list comprehension and Exception handling indicies with i to remove the error results and only keep the good ones. I don't know if this is possible hence this question. I've looked at the "better ways to implement nested try catch blocks" question however it wasn't useful to me because It provided a solution in delphi and I didn't understand exactly how it worked or if it even worked the way I want mine to work. I at first thought the finally block might be what I needed but that only runs after the catch is executed or if there is no exception, after the try. I need something that postpones the catch block untill the try is complete and I can't think of/find anything that does that.
What are you, crazy?
right now you may be asking, what the hell is the point of this? Well imagine if you had the above problem but instead of two ways to parse the string you had 10 or 100. Pretty quickly, exception handling that with nested try catch blocks would be nigh impossible. I've seen solutions where the catch block calls a custom exception method that then at least takes care of the bad formatting. It looked like this:
try{
//bad code
}
catch{
trysomethingelse();
}
trysomethingelse(){
//equally bad code
catch{
//ya done screwed up son
}
}
However I'm not satisfied because it means that you need a million different method names just to potentially handle one error. Imagine the error would always be the same you just need to try 100 different string parsing methods. Its always going to be a numberformatException if you're trying to convert a string to a number so why have a million catch blocks just for the same error? I want to try to do this with one theoretical catch block that specifies one error that happens many times over in the try block.
You build a list/array of parsers, then iterate that list, catching exception for each.
With Java 8 method references, this is real easy. First, define a Parser functional interface that allows exceptions to be thrown:
#FunctionalInterface
public interface Parser {
Object parse(String text) throws Exception;
}
Next, build your array of parsers to try:
Parser[] parsers = {
Integer::valueOf,
Double::valueOf,
BigInteger::new,
BigDecimal::new
};
Finally, try them one at a time:
String text = "45.8";
Object[] results = new Object[parsers.length];
for (int i = 0; i < parsers.length; i++) {
try {
results[i] = parsers[i].parse(text);
} catch (Exception e) {
results[i] = e;
}
}
Now you can go through the results:
for (Object result : results) {
if (result instanceof Exception)
System.out.println("Error: " + result);
else
System.out.println("Parsed as " + result.getClass().getSimpleName() + ": " + result);
}
Output
Error: java.lang.NumberFormatException: For input string: "45.8"
Parsed as Double: 45.8
Error: java.lang.NumberFormatException: For input string: "45.8"
Parsed as BigDecimal: 45.8
Or put the parsed objects and the exceptions into two different lists. Up to you.
You can do something like this:
interface Parser {
Number parse(String);
}
class IntegerParser implements Parser {
#Override
public Number parse(String) {
// implementation here
}
}
class FloatParser implements Parser {
}
List<Parser> parsers = asList(new FloatParser(), new IntegerParser(), ...);
Number result = null;
List<NumberFormatException> exceptions = new ArrayList<>();
for (Parser parser : parsers) {
try {
result = parser.parse(stringToParse);
break;
} catch (NumberFormatException e) {
exceptions.add(e);
}
}
if (result != null) {
// parsed ok with some parser
// probably discard exceptions
} else {
// show exceptions from the list
}
Try this:
public static void test() {
final String num = "1.0";
final ArrayList<Object> listofResults = new ArrayList<>();
final java.util.function.Function<String, ?>[] parseMethods = new java.util.function.Function[3];
parseMethods[0] = Integer::parseInt;
parseMethods[1] = Float::parseFloat;
parseMethods[2] = Integer::parseInt;
int[] badIndeces = IntStream.range(0, parseMethods.length).map(i -> {
try {
listofResults.add(parseMethods[i].apply(num));
return -i-1;
} catch (NumberFormatException exc) {
return i;
}
}).filter(i -> i >= 0).toArray();
for (int element : badIndeces) {
System.out.println(element);
}
}
I've learned that Exception is slow:
How slow are Java exceptions?
but this article(http://blogs.atlassian.com/2011/05/if_you_use_exceptions_for_path_control_dont_fill_in_the_stac/) says that we can use Exception to simulate a goto statement:
so I think it's ok to write my code like this:
public class MyService {
public Result service(int i) {
Result result = new Result();
try {
Util.checkCommonArguments(i);
//my business logic...
if ((i % 2) != 0) {
throw new BizException("002", "can not be odd");
}
if (i > 200) {
throw new BizException("003", "can not be greater than 200");
}
// the normal processing...
result.setCode("000");
result.setDesc("ok");
} catch (BizException e) {
result.setCode(e.getCode());
result.setDesc(e.getMessage());
} catch (Exception e) {
result.setCode("999");
result.setDesc("system error");
}
return result;
}
}
class Util {
public static void checkCommonArguments(int input) {
if (input < 0) {
throw new BizException("001", "can not be negative.");
}
//maybe more
}
}
class Result {
private String code;
private String desc;
//getter and setter
}
class BizException extends RuntimeException {
private String code;
public BizException(String code, String message) {
super(message);
this.code = code;
}
#Override
public Throwable fillInStackTrace()
{
return this;
}
}
but 'dont fill in the stack trace' does not work:
// throw but catch, but not Filling in exception stack traces
public void method5(int i) {
try {
value = ((value + i) / i) << 1;
// i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
// an AND operation between two integers. The size of the number plays
// no role. AND on 32 BIT always ANDs all 32 bits
if ((i & 0x1) == 1) {
throw new MyBizException();
}
} catch (MyBizException e) {
//maybe do something
}
}
method5's cost time is almost the same as:
// This one will regularly throw one
public void method3(int i) throws Exception {
value = ((value + i) / i) << 1;
// i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
// an AND operation between two integers. The size of the number plays
// no role. AND on 32 BIT always ANDs all 32 bits
if ((i & 0x1) == 1) {
throw new Exception();
}
}
Now I'm confused. On one side, I want my code clean and clear(like the class 'MyService'). On the other side, Exception is really slow.
Should I use Exception to simulate a goto statement? Thanks.
Don't use exceptions for normal program flow. They are for exceptional circumstances beyond the developer's control. They are slow, inefficient, and designed for error handling, not business logic.
Stimulating a goto is a bad design decision in today's development environment anyways. They are confusing to follow, and difficult to maintain. Refactor your code to use breaks or other control logic instead.
Using exception for flow control is neither in the interest of good design nor efficient. At the very minimum this will create unnecessary objects. I would encourage you to have a look at Joshua Bloch's "Effective Java" which explicitly covers this topic.
I've been working on a java project for the last couple days, and while things have gone smoothly to this point, I have hit a bit of a snag.
The point of the project is to create a query of sorts, where the user searches for a report using a GUI interface and the app spits out all related data.
Ex: report all where quality > 3
I use a StringTokenizer object to break the String down and evaluate each token. The first token MUST be report, the second token MUST be all, third token MUST be where, the fourth token MUST be either quality, basePrice or numInStock, the fifth token MUST be a relational operator(> < <= >= ==). We were instructed to throw custom checked exceptions if any of the tokens do not match what they should be. So far I have evaluated each token, and throw an Exception if the expected token is not what it should be.
Now once I reach the relational operator, i'm supposed to dump it into a new String called optok. The problem is, I can't seem to get my program to do this and i'm having a hard time figuring out how to do so. I've tried many different things and nothing seems to work.
The final goal is, once all the tokens have been evaluated and checked, to call a method to print the correct query and all data that goes along with said query. If one of the tokens doesn't match, an Exception is thrown.
Here is my code for evaluating each token, to check that it is in the correct format:
public void detectUserInput(String input) throws MissingInputException
{
if (input.equals(""))
{
System.out.println("Null input");
throw new MissingInputException();
}
else
{
System.out.println("Input is not null");
}
}//end detectUserInput
public void countTokens(String input) throws IncorrectFormatException
{
StringTokenizer tokenLength = new StringTokenizer(input, " ,");
if (tokenLength.countTokens() < 6)
{
throw new IncorrectFormatException();
}
}//end countTokens
public void evaluateTokens(String input) throws IllegalStartOfQueryException,
InvalidSelectorException,
InvalidQualifierException,
InvalidLValueException,
InvalidOperatorException
{
StringTokenizer testTokens = new StringTokenizer(input, " ,");
if (!testTokens.nextToken().equalsIgnoreCase("report"))
{
throw new IllegalStartOfQueryException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("all"))
{
throw new InvalidSelectorException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("where"))
{
throw new InvalidQualifierException();
}
else if (!testTokens.nextToken().matches("quality|numInStock|basePrice"))
{
throw new InvalidLValueException();
}
else if (!testTokens.nextToken().matches(">|<|>=|<=|=="))
{
throw new InvalidOperatorException();
}
//here is where I try to take the relational operator
//and dump it into optok, after all the previous input
//has been validated, but it doesnt work :(
while (testTokens.hasMoreTokens())
{
tok = testTokens.nextToken();
if (tok.matches("<|>|>=|<=|=="))
{
optok = tok;
}
}
}//end evaluateTokens
And here is the actionPerformed() of my program that reacts when the user types their query into the TextField and presses the GO! JButton :
private class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
if (ev.getSource() == goBtn)
{
input = queryFld.getText();
try
{
detectUserInput(input);
countTokens(input);
evaluateTokens(input);
}
catch (MissingInputException mie)
{
errorFld.setText("Enter an expression");
queryFld.setText("");
System.err.println(mie);
mie.printStackTrace();
}
catch (IncorrectFormatException ife)
{
errorFld.setText("Too few terms");
queryFld.setText("");
System.err.println(ife);
ife.printStackTrace();
}
catch (IllegalStartOfQueryException isqe)
{
errorFld.setText("Word REPORT expected");
queryFld.setText("");
System.err.println(isqe);
isqe.printStackTrace();
}
catch (InvalidSelectorException ise)
{
errorFld.setText("Selector must be ALL");
queryFld.setText("");
System.err.println(ise);
ise.printStackTrace();
}
catch (InvalidQualifierException iqe)
{
errorFld.setText("Qualifier error - keyword WHERE missing");
queryFld.setText("");
System.err.println(iqe);
iqe.printStackTrace();
}
catch (InvalidLValueException ilve)
{
errorFld.setText("Invalid query. quality, numInStock, "
+ "or basePrice expected");
queryFld.setText("");
System.err.println(ilve);
ilve.printStackTrace();
}
catch (InvalidOperatorException ioe)
{
errorFld.setText("InvalidOperatorException. < <= > >= == expected");
queryFld.setText("");
System.err.println(ioe);
ioe.printStackTrace();
}
}
}//end actionPerformed
}//end ButtonHandler
I apologize if this seems trivial, but i'm having a really hard time figuring it out for some reason. I appreciate any input or suggestions. If i'm missing any info needed please let me know and i'll add it asap. Also, here are the instructions for this segment:
11) Now, focus on the evaluateAll method. Get the next token. It should be any one of 3 words:
“basePrice” or “quality” or “numInStock” . If it is not, place the message “Invalid query, quality, numInStock or basePrice expected. If is one of those 3 words, you expect a relational operator, so get the next token, but save it in a new String, call it optok. If it is not a correct operator, place the message “invalid query,
You now have two Strings: token which is either “basePrice” or “quality” or “numInStock” and an optok which is one of the 5 relational operators listed above.
Thanks in advance :)
You didn't post a stacktrace, so I'm guessing you're not having an exception, and reading from your code I'm trying to understand what could be happening .. so I might be wrong.
It seems to me that you are using a tokenizer. A tokenizer is like a stream, once you call nextToken() it returns the token, and unless you save it somewhere the next call to nextToken() will make the previous one not accessible.
So, where you make :
else if (!testTokens.nextToken().matches("quality|numInStock|basePrice"))
{
throw new InvalidLValueException();
}
else if (!testTokens.nextToken().matches(">|<|>=|<=|=="))
{
throw new InvalidOperatorException();
}
You are consuming the tokens. As a result, when you get to the while :
while (testTokens.hasMoreTokens()) {
All the tokens are consumed, so it will not iterate here.
You should instead save your tokens in variables, so that you can both check and the use them :
StringTokenizer testTokens = new StringTokenizer(input, " ,");
if (!testTokens.nextToken().equalsIgnoreCase("report"))
{
throw new IllegalStartOfQueryException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("all"))
{
throw new InvalidSelectorException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("where"))
{
throw new InvalidQualifierException();
}
// TODO here i use local variables, since you need to use these outside this method,
// maybe use class fields or whatever else
String subject = testTokens.nextToken();
String opttok = testTokens.nextToken();
if (!subject.matches("quality|numInStock|basePrice"))
{
throw new InvalidLValueException();
}
else if (!opttok.matches(">|<|>=|<=|=="))
{
throw new InvalidOperatorException();
}
// done, now you have opttok and subject
I had some difficulty with the title, wasn't sure how to word it more accurately.
I'm having this issue, I have a several methods which ask the user for 3 Double inputs.
For each input it checks if it's valid (for example if its a positive value), if it's not it throws an IllegalArgumentException. Now I made a Tester class to check if the methods are working properly. It's supposed to catch the exception thrown by the methods and re-ask the user for the input which caused that specific exception.
All 3 methods throw and IllegalArgumentException but the error message is different for each one. Is there anyway (when catching the exception) to see which input cause the error? Here's a sample of my code:
public class account
{
double value;
public account(double initialValue)
{
if (initialValue < 0)
{
throw new IllegalArgumentException("Initial value cannot be negative.");
}
value = initialValue;
}
public add(double addValue)
{
if (addValue < 0)
{
throw new IllegalArgumentException("Added value cannot be negative.");
}
value = value + addValue;
}
}
and the tester class would be something like:
public class accountTester
{
public static void main(String[] args)
{
try
{
double initialValue = Double.parseDouble(JOptionPane.showInputDialog("Enter initial value"));
account acc = new account(initialValue);
double addValue = Double.parseDouble(JOptionPane.showInputDialog("Enter value to add"));
acc.add(addValue);
} catch (Exception e) {
System.out.println("Wrong ammount");
initialValue = Double.parseDouble(JOptionPane.showInputDialog("Re-enter ammount"));
}
}
So what would I have to change in the tester class to throw that code only if the IllegalArgumentException is "Initial value cannot be negative."
Sorry if I made this hard to understand.
EDIT: According to my prof, we're supposed to use do
String error = e.toString;
if (error.contains("Added value cannot be negative.")
{
//DO CODE FOR FIRST ERROR
}
I know this isn't the most proper way of doing it though.
Since you can't match over Strings like you would do in a functional language you have to provide three different kind of objects if you want to be able to distinguish them using the try-catch mechanics.
Or with a simplified approach attach a parameter to the exception so that you can use just a catch clause but you could behave differently. Something like
class MyIllegalArgumentException extends IllegalArgumentException {
public int whichParameter;
public MyIllegalArgumentException(String string, int which) {
super(string);
whichParameter = which;
}
}
now you can:
catch (MyIllegalArgumentException e) {
if (e.whichParameter == 0)
..
else if (e.whichParameter == 1)
..
}
You could also check the string for equality but this would be really not a good design choice, you could also have many try-catch blocks but this is not always possible.
After having expanded your code the solution is easy:
public static void main(String[] args) {
try {
double initialValue = ...
account acc = new account(initialValue);
} catch (IllegalArgumentException e) {
...
}
try {
double addValue = ...
acc.add(addValue);
} catch (Exception e) {
System.out.println("Wrong ammount");
initialValue = Double.parseDouble(JOptionPane.showInputDialog("Re-enter ammount"));
}
}
Surround each method call with its own try/catch block?
In your catch block you should only catch IllegalArgumentException. Then what you can do is invoke the getMessage() function which will enable you to do a very simple String.equals call.
In my Java code, I have a function called getAngle() which sometimes throws a NoAngleException. Is the following code the best way of writing a function that keeps calling getAngle() until no exception is thrown?
public int getAngleBlocking()
{
while(true)
{
int angle;
try
{
angle = getAngle();
return angle;
}
catch(NoAngleException e)
{
}
}
}
Or would it be a better idea to rewrite getAngle() to return NaN upon error?
I'm surprised to read some of the answers to this thread because this scenario is precisely the reason checked exceptions exist. You could do something like:
private final static int MAX_RETRY_COUNT = 5;
//...
int retryCount = 0;
int angle = -1;
while(true)
{
try
{
angle = getAngle();
break;
}
catch(NoAngleException e)
{
if(retryCount > MAX_RETRY_COUNT)
{
throw new RuntimeException("Could not execute getAngle().", e);
}
// log error, warning, etc.
retryCount++;
continue;
}
}
// now you have a valid angle
This is assuming that something outside of the process changed in the meantime. Typically, something like this would be done for reconnecting:
private final static int MAX_RETRY_COUNT = 5;
//...
int retryCount = 0;
Object connection = null;
while(true)
{
try
{
connection = getConnection();
break;
}
catch(ConnectionException e)
{
if(retryCount > MAX_RETRY_COUNT)
{
throw new RuntimeException("Could not execute getConnection().", e);
}
try
{
TimeUnit.SECONDS.sleep(15);
}
catch (InterruptedException ie)
{
Thread.currentThread().interrupt();
// handle appropriately
}
// log error, warning, etc.
retryCount++;
continue;
}
}
// now you have a valid connection
I think you should investigate why getAngle() is throwing an exception and then resolve the problem. If this is random, like input from a sensor, maybe you should wait some time until calling again. You could also make getAngle() blocking, that means getAngle() will wait until a good result is acquired.
Ignoring how you're solving your problem you should have some kind of timeout mechanism, so you don't end up in an endlessloop. This supposes that you don't want to have an possibly infinite loop, of course.
You want to call a method as long as it throws an exception?
This is not programming. You should use the debugger and take a look at the real issue.
And you should never catch an exception without any message or logging!
Could you not have used recursion?
i.e.;
public int getAngleBlocking()
{
int angle;
try
{
angle = getAngle();
return angle;
}
catch(NoAngleException e)
{
return getAngleBlocking();
}
}
}
I would not recommend to do it that way, because when getAngle() never returns a valid value (always throws an exception for some reason) you end up in an endless loop. You should at least define a break condition (e.g. timeout) for this case.
In the end I opted for returning a NaN value, as this prevents careless use of Integer.MIN_VALUE somewhere else.
public float getAngle(boolean blocking)
{
while(true)
{
int dir = getDirection();
if(dir == 0 && !blocking)
return Float.NaN;
else
return (dir - 5) * 30;
}
}
Unless you are using a class that is entirely outside of your control, you really want to reconsider throwing an exception to indicate no angle.
Sometimes, of course, this is not possible either because the class is not yours, or, it is not possible to make dual use of the returned type as both the result or error status.
For example, in your case, assuming all integer (negative and 0) degrees are possible angles, there is no way for you to return an int value that indicates error and is distinct from a valid angle value.
But lets assume your valid angles are in range -360 -> 360 (or equiv. in radians). Then, you really should consider something like:
// assuming this ..
public static final int NO_ANGLE_ERROR = Integer.MIN_VALUE;
// do this
public int getAngleBlocking()
{
int angle;
do {
angle = getAngle();
}while(angle == NO_ANGLE_ERROR);
}
Never use Exceptions to handle flow logic in your code.
as suggested first check why you sometimes get the execption