Struggling with exceptions, try/catch block and singleton in Java - java

I am trying to learn to work with error handling/throwing exceptions in Java.
I have a class, UserDatabase, holding a collection of students, and it should also save the collection to a file.
What I'm fairly sure that I haven't done correctly, is the methods for file handling. Method public boolean saveDatabase should not throw exceptions and be handled in a try-catch, and use the encode method from the student class on Student objects, to write every object as a line in the file. This one is compiling, but it looks off to me. In the book it says write the method public boolean saveDatabase(); and as you can see I changed the header for it to make sense to me. This, mainly because I don't know how to write a method with the header ending with ();
Method public boolean loadDatabase should also handle possible IO errors and return false if one occurs. For every line in the field it should create a student object by the constructor public Student(String encodedStudent) from the sudent class. If a line in the file cannot be decoded as a student it should throw a new exception, DatabaseFormatException (this is a seperate class). This one is also listed as public boolean loadDatabase(); in the book. Let's face it, this one is completely off. I have no idea what to do and I have been working with it for hours and hours, reading books, reading online, I am lost.
Here's my code:
/**
* This method should not throw exceptions.
* By using a try/catch block, we anticipate possible failures.
* We recognize that these actions might fail and throw errors.
*/
public boolean saveDatabase() throws IOException {
//This method is using the encode method on student objects and should
//write each object as a line in the file.
String encode = null;
boolean saved;
try {
encode = null;
userdatabase.saveDatabase();
saved = false;
}
catch (IOException e) {
System.out.println("Error");
saved = false;
}
finally {
if(encode.equals(students)) {
//System.out.println("Students" + students)?;
saved = true;
}
}
return saved;
}
/**
* Method loadDatabase should handle possible IO errors, and return false
* if one occurs. Otherwise, it should return true and create a new
Student object
* by using the constructor public Student(String encodedStudent).
* If a line cannot be decoded as a student, the method should throw a
new
* exception "DatabaseFormatException".
*
*/
public boolean loadDatabase() throws IOException,DatabaseFormatException {
//Attempting to use the String encodedStudent constructor from Student class
String encodedStudent = null;
boolean loaded;
try {
//Attempting to create possible IO errors returning false if they occur
enco dedStudent = null;
//UserDatabase.loadDatabase(encodedStudent);
loaded = false;
}
catch(IOException e) {
if (encodedStudent == null) {
System.out.println("Error");
loaded = false;
}
}
//Trying a for each loop to throw a DatabaseFormatException
for(Student student : students) {
//This is supposed to throw a DatabaseFormatException if a
//line in the file cannot be decoded as a student!
if(student.getName.isEmpty() && this.course.isEmpty()) {
throw new DatabaseFormatException(
"No student found");
}
}

Your code should be
public boolean saveDatabase() {
try {
// maybe do some more work...
userdatabase.saveDatabase();
return true;
} catch (IOException e) {
return false;
}
}
Simply return true/false depending on wether an exception occurred or not. Drop the saved since you no longer need it. And drop the encode since you did not need it in the first place and never assigned a value to it.

Related

getConstructor() return a constructor that is not implemented

I'm learning some of the reflection features in Java and I got a strange problem testing the getConstructor() function with this Class.
public class IntegerSequence {
private Integer[] elements;
private int size;
private int MAX_SIZE = 100;
public IntegerSequence() {
elements = new Integer[MAX_SIZE];
size = 0;
System.out.println("Hello Guys");
}
}
The function returns a valid constructor but the "Hello Guys" message is never printed.
Furthermore, If I delete the constructor of IntegerSequence, it also return a valid constructor and doesn't throw any exception, even if there is no one anymore in IntegerSequence class.
I read that getConstructor() only returns a constructor coded in the class and not one made automatically by Java so I'm a bit lost.
Here is the code that use the function and it's output:
public void invokeDefaultConstructor(Class c){
Constructor build = null;
try {
build = c.getConstructor();
} catch (NoSuchMethodException e) {
System.out.println(e);
e.printStackTrace();
}
System.out.println(build.toString());
System.out.println(build.getName());
}
console Output:
public generics.IntegerSequence()
generics.IntegerSequence
Do you know what could cause that kind of behaviour ?
The function return a valid constructor but the "Hello Guys" message is never printed.
That's expected, since you never call the constructor anywhere. You only get the constructor from the class.
I read that getConstructor() only return a constructor coded in the class and not one made automatically by Java
I don't know where you read that. The javadoc certainly doesn't say that.

Evaluating user input using StringTokenizer while utilizing custom checked exceptions

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

Missing Return Statement

i am attempting to take the value of a textfield and make apply it to a method in order to search a textfile for that value. But in my method i am shown a Missing Return Value error and cannot seem to make it work. below is my code:
submitsearch.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
whatToSearch = searchfield.getText();
result = SearchString(whatToSearch);
}
});
}
public String SearchString(String result)
{
String input;
try{
String details, id, line;
int count;
Scanner housenumber = new Scanner(new File("writeto.txt"));
while(housenumber.hasNext())
{
id = housenumber.next();
line = housenumber.nextLine();
{
if(!housenumber.hasNext())
JOptionPane.showMessageDialog(null,"No Properties with this criteria");
}
if(result.equals(id));
{
JOptionPane.showMessageDialog(null,id + line );
}
}
}
catch(IOException e)
{
System.out.print("File failure");
}
}
}
Addendum:
In SearchString i am hoping to search my textfile for the value entered in my textfield display it in a JOptionPane. Although i now have the return statement when i click search i am shown all of the records in JOptionPanes one by one regardless of whether they match my search
You have declared the function with a return type of String, so it must return a String on all code paths. If you don't need it to return anything, use void instead.
Add a return null; after catch block.
The method signature says that it returns a String. That implies no matter what flow your code takes, the method should return a value. But when an exception happens, there is no return. Hence you must specify a return value in the case when an exception happens

jsr223 + writing a script interpreter

OK. ScriptEngine.eval(String string) evaluates a string in its entirety, and ScriptEngine.eval(Reader reader) evaluates the input from a Reader in its entirety.
So if I have a file, I can open a FileInputStream, wrap a Reader around it, and call scriptEngine.eval(reader).
If I have a complete statement as a string, I can call scriptEngine.eval(string).
What do I do if I need to implement an interactive interpreter? I have a user who is interactively typing in a multiline statement, e.g.
function f() {
return 3;
}
If I read the input line by line, and use the String form of eval(), I'll end up passing it incomplete statements, e.g. function f() { and get an error.
If I pass in a Reader, the ScriptEngine will wait forever until the input is complete, and it's not interactive.
Help!
Just to clarify: the problem here is that I can only pass ScriptEngine.eval() complete statements, and as the customer of ScriptEngine, I don't know when an input line is complete without some help from the ScriptEngine itself.
Rhino's interactive shell uses Rhino's Context.stringIsCompilableUnit() (see LXR for usage and implementation).
I implemented something that works OK with Java SE 6 Rhino (Javascript) and Jython 1.5.2 (Python), using a fairly simple approach similar to Rhino's interactive shell (see my remark at the end of the question):
Keep a pending list of input lines not yet evaluated.
Try compiling (but not evaluating) the pending input lines.
If the compilation is OK, we may be able to execute pending input lines.
If the compilation throws an exception, and there is an indication of the position (line + column number) of the error, and this matches the end of the pending input, then that's a clue that we're expecting more input, so swallow the exception and wait for the next line.
Otherwise, we either don't know where the error is, or it happened prior to the end of the pending input, so rethrow the exception.
If we are not expecting any more input lines, and we only have one line of pending input, then evaluate it and restart.
If we are not expecting any more input lines, and the last one is a blank one (per #karakuricoder's answer) and we have more than one line of pending input, then evaluate it and restart. Python's interactive shell seems to do this.
Otherwise, keep reading input lines.
What I didn't want to happen is either:
users get annoyed having to enter extra blank lines after single-line inputs
users enter a long multi-line statement and only find out after the fact that there was a syntax error in the 2nd line.
Here's a helper class I wrote that implements my approach:
import java.lang.reflect.Method;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
public class ScriptEngineInterpreter
{
private static final boolean DEBUG = false;
final private ScriptEngine engine;
final private Bindings bindings;
final private StringBuilder sb;
private int lineNumber;
private int pendingLineCount;
private boolean expectingMoreInput;
/**
* #param engine ScriptingEngine to use in this interpreter
* #param bindings Bindings to use in this interpreter
*/
public ScriptEngineInterpreter(ScriptEngine engine, Bindings bindings)
{
this.engine = engine;
this.bindings = bindings;
this.sb = new StringBuilder();
this.lineNumber = 0;
reset();
}
/** #return ScriptEngine used by this interpreter */
public ScriptEngine getEngine() { return this.engine; }
protected void reset() {
this.sb.setLength(0);
this.pendingLineCount = 0;
setExpectingMoreInput(false);
}
/** #return whether the interpreter is ready for a brand new statement. */
public boolean isReady() { return this.sb.length() == 0; }
/**
* #return whether the interpreter expects more input
*
* A true value means there is definitely more input needed.
* A false value means no more input is needed, but it may not yet
* be appropriate to evaluate all the pending lines.
* (there's some ambiguity depending on the language)
*/
public boolean isExpectingMoreInput() { return this.expectingMoreInput; }
protected void setExpectingMoreInput(boolean b) { this.expectingMoreInput = b; }
/**
* #return number of lines pending execution
*/
protected int getPendingLineCount() { return this.pendingLineCount; }
/**
* #param lineIsEmpty whether the last line is empty
* #return whether we should evaluate the pending input
* The default behavior is to evaluate if we only have one line of input,
* or if the user enters a blank line.
* This behavior should be overridden where appropriate.
*/
protected boolean shouldEvaluatePendingInput(boolean lineIsEmpty)
{
if (isExpectingMoreInput())
return false;
else
return (getPendingLineCount() == 1) || lineIsEmpty;
}
/**
* #param line line to interpret
* #return value of the line (or null if there is still pending input)
* #throws ScriptException in case of an exception
*/
public Object interpret(String line) throws ScriptException
{
++this.lineNumber;
if (line.isEmpty())
{
if (!shouldEvaluatePendingInput(true))
return null;
}
++this.pendingLineCount;
this.sb.append(line);
this.sb.append("\n");
CompiledScript cs = tryCompiling(this.sb.toString(), getPendingLineCount(), line.length());
if (cs == null)
{
return null;
}
else if (shouldEvaluatePendingInput(line.isEmpty()))
{
try
{
Object result = cs.eval(this.bindings);
return result;
}
finally
{
reset();
}
}
else
{
return null;
}
}
private CompiledScript tryCompiling(String string, int lineCount, int lastLineLength)
throws ScriptException
{
CompiledScript result = null;
try
{
Compilable c = (Compilable)this.engine;
result = c.compile(string);
}
catch (ScriptException se) {
boolean rethrow = true;
if (se.getCause() != null)
{
Integer col = columnNumber(se);
Integer line = lineNumber(se);
/* swallow the exception if it occurs at the last character
* of the input (we may need to wait for more lines)
*/
if (col != null
&& line != null
&& line.intValue() == lineCount
&& col.intValue() == lastLineLength)
{
rethrow = false;
}
else if (DEBUG)
{
String msg = se.getCause().getMessage();
System.err.println("L"+line+" C"+col+"("+lineCount+","+lastLineLength+"): "+msg);
System.err.println("in '"+string+"'");
}
}
if (rethrow)
{
reset();
throw se;
}
}
setExpectingMoreInput(result == null);
return result;
}
private Integer columnNumber(ScriptException se)
{
if (se.getColumnNumber() >= 0)
return se.getColumnNumber();
return callMethod(se.getCause(), "columnNumber", Integer.class);
}
private Integer lineNumber(ScriptException se)
{
if (se.getLineNumber() >= 0)
return se.getLineNumber();
return callMethod(se.getCause(), "lineNumber", Integer.class);
}
static private Method getMethod(Object object, String methodName)
{
try {
return object.getClass().getMethod(methodName);
}
catch (NoSuchMethodException e) {
return null;
/* gulp */
}
}
static private <T> T callMethod(Object object, String methodName, Class<T> cl) {
try {
Method m = getMethod(object, methodName);
if (m != null)
{
Object result = m.invoke(object);
return cl.cast(result);
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Create a method that reads from the keyboard (Scanner class) and creates a complete string from multiple lines of input. Enter on a blank line signals the end of user input. Pass the string into the eval method.

Why i am getting Error if i use try catch

i wrote an function like
public static boolean check()throws Exception
{
if(a=="asd")
return true;
else
return false;
}
this works fine
but if i use
public static boolean check()
{
try
{
if(a=="asd")
return true;
else
return false;
}
catch(Exception e)
{
}
}
it says you need to return an value,,,, is there is any difference between these two???
you need to return something in the catch, a method always need to return something, even in catch, unless you throw/rethow an exception.
Yes, there is a difference. Your second code block will catch any exception from the if statement and swallow it, and then resume running after the catch block. But there is no return statement there, so if there is any exception, the function will have no return value.
The first code block, on the other hand, uses throws to indicate that Exception descendants may escape from it instead of being caught, so it doesn't need to catch and handle anything itself, and the compiler is prepared to allow the function to not return anything (due to exiting early from an exception).
Java has methods, not functions. So you didn't write a function, but a method. Also, comparing strings with == does not work in Java. You have to call the equals() method instead:
if (a.equals("asd"))
The problem in your second piece of code is this: What happens if an exception occurs? The content of the catch block is executed, and after that the rest of the method is executed. Note that there is no code after the catch block. But the method requires that you return a boolean - you're missing a return statement. Change it like this:
public static boolean check()
{
try
{
if (a.equals("asd"))
return true;
else
return false;
}
catch(Exception e)
{
}
// You need to add a return statement here
return false;
}
There are some more comments that can be made about your code.
First of all, it's always a bad idea to leave a catch block empty. Because when an exception is caught, nothing will happen, and you'll never know that something went wrong. Always handle exceptions appropriately.
Also, code like this:
if (a.equals("asd"))
return true;
else
return false;
can be simplified like this:
return a.equals("asd");
The result of the expression a.equals("asd") is already a boolean; why would you check again if it's true or false and then return true or false?
Not all paths in the code will return a value. Since you have a catch there, if an exception is thrown, no value will be returned because the code in the catch will execute.
I think you should return the value at the end of function after catch. Try to store result in one boolean variable and return that variable after catch. This may solve your problem
A premise:
a=="asd" is not 'wrong' but probably it is better to use a.equals("asd") because == compares pointers, not equality. For example ("asd"=="asd") == false but ("asd".equals("asd")) == false
If if(a=="asd") throws an exception, the flow goes in the catch, and then it exits without ever finding the return statement. the correct code could have a return statement inside the catch block
Jesper's answer pretty much covers it. I needed to show some code so therefore this separate answer.
You will have to decide in each situation how to handle exceptions. Jesper and LordSAK both chose to return 'false'. A problem with this is that you can't distinguish the error condition from the case that 'a' is not equal to "asd".
A possible solution is to change the method's return type to Boolean (the Object version of the primitive boolean) and return 'null' in case of an exception
public static Boolean check() {
try {
return "asd".equals(a);
}
catch(Exception e) {
return null;
}
}
Another option is to re-throw your exception as an unchecked exception:
public static boolean check() {
try {
return "asd".equals(a);
}
catch(Exception e) {
throw new RuntimeException("Problem during check", e);
}
}
A drawback of this approach is that the code calling your check() method does not expect a runtime exception to be thrown. Because this type of exception is unchecked the developer will not get a compiler warning if he doesn't surround the call to check() with try-catch.
A third option is to just declare the exception and let your calling code handle it. A full example:
import org.apache.log4j.Logger;
public class Checker {
private static final Logger LOG = Logger.getLogger(Checker.class);
private String a;
public Checker(String value) {
a = value;
}
public boolean check() throws Exception {
return "asd".equals(a);
}
public static void main(String[] args) {
Checker app = new Checker("Stackoverflow");
try {
app.check();
}
catch(Exception e) {
LOG.error("Problem during check", e);
}
}
}
An advantage is that you don't have to decide which value check() returns in case of an error, but instead you just return the error itself. This is actually the whole idea of 'throwing' exceptions.
As a rule of thumb: if you can't handle an exception within the method itself, then throw it and let the calling code deal with it.
An example from the wild: A method handling an exception itself.
private static final long DEFAULT_TIMEOUT = 60000;
public long getTimeout(String timeoutArg) {
try {
return Long.parseLong(timeoutArg);
}
catch(NumberFormatException e) {
return DEFAULT_TIMEOUT;
}
}
NB: I didn't compile or run any of this code, so there might be typos.

Categories

Resources