Okay, I have never had this problem before so I am not sure how to word it or to repair it, I am building a java application that creates dealers, in that application I have the parameters passed in to the DealerFactory.createDealer method and proceed to first check if that dealer exists with a conditional statement that looks like this:
if (DealerFactory.fetchDealer(loginId).getLoginId().equals(loginId)) {
throw new Exception("Sorry That Dealer Already Exists");
} else if (DealerFactory.fetchDealer(loginId).getId().equals(DNo)){
throw new Exception("Sorry That Dealer Already Exists");
} else {
<< proceed with the rest of the method here >>
I have seen this done before so as to check the availability of the username and the id of the person being created. However after running it I found that if I create the dealer and the condition evaluates to true the if statement works just fine letting me know that I have created a user that already exists and I need to create him/her with new a different Id and username. However if the condition evaluates to false I never seem to make it into the else portion of the statement, I am getting no errors, no compilation issues, and no exceptions I have written the statement differently to try that, which wasn't really any different it just looked syntactically different:
if (DealerFactory.fetchDealer(loginId).getLoginId().equals(loginId)
|| DealerFactory.fetchDealer(loginId).getId().equals(DNo)) {
throw new Exception("Sorry That Dealer Already Exists");
}
I have included println statements to follow the program through its run and when the condition evaluates to false I never make it into the else statement. I cant seem to figure out why it is breaking on the condition statement when it is evaluated to false, any thoughts?
edit:::
Ok so that I can be of more assistance in helping you guys help me lol here is the method in its entirety, I apologize for not posting it in the first place
public static int create(String DNo, String name, String admin,
String loginId, String password, String callSrc, String voiSys,
String whoCall, String callBrt, String active, String adfEmail)
throws SQLException, Exception {
int validateResult = 0;
if (DealerFactory.fetchDealer(loginId).getLoginId().equals(loginId)
|| DealerFactory.fetchDealer(loginId).getId().equals(DNo)) {
throw new Exception("Sorry That Dealer Already Exists");
}
try {
DealerFactory.pool = DBConnector.getInstance();
DealerFactory.connect = DBConnector.getConnection();
DealerFactory.preparedStatement = connect
.prepareStatement("Insert Into Dealers (DNo, Dealer, Admin, Login, Password, CallSrc, VoiSys, WhoC, CBrt, Active, ADFemail) "
+ "values(?,?,?,?,?,?,?,?,?,?,?)");
DealerFactory.preparedStatement.setString(1, DNo);
DealerFactory.preparedStatement.setString(2, name);
DealerFactory.preparedStatement.setString(3, admin);
DealerFactory.preparedStatement.setString(4, loginId);
DealerFactory.preparedStatement.setString(5, password);
DealerFactory.preparedStatement.setString(6, callSrc);
DealerFactory.preparedStatement.setString(7, voiSys);
DealerFactory.preparedStatement.setString(8, whoCall);
DealerFactory.preparedStatement.setString(9, callBrt);
DealerFactory.preparedStatement.setString(10, active);
DealerFactory.preparedStatement.setString(11, adfEmail);
validateResult = DealerFactory.preparedStatement
.executeUpdate();
} catch (SQLException ex) {
System.err.println("Error: " + ex + "\n");
ex.printStackTrace();
} finally {
DBUtils.closePrepStatement(DealerFactory.preparedStatement);
DealerFactory.pool.freeConnection(DealerFactory.connect);
}
return validateResult;
}
First things first, you shouldn't chain methods like that due to dangers of NullPointerException
So this part:
if(DealerFactory.fetchDealer(loginId).getLoginId().equals(loginId))
Could look something like this:
if(DealerFactory.fetchDealer(loginId) != null &&
DealerFactory.fetchDealer(loginId).getLoginId().equals(loginId))
Or you could have a separate null check before all your if statements.
However, what you are doing is an overkill. This whole part:
DealerFactory.fetchDealer(loginId).getLoginId()
Returns null if you cannot find a dealer or loginId that you already have.
Assuming your fetchDealer() method returns null if dealer cannot be found.
Instead of:
if(DealerFactory.fetchDealer(loginId).getLoginId().equals(loginId)))
You can just do:
if(DealerFactory.fetchDealer(loginId) != null)
Another improvement you could do is to add a method to DealerFactory called dealerExists(String id) declared something like this:
boolean dealerExists(String id) {
return (YOUR_DATA_STRUCTURE_OF_DEALERS.get(id) != null);
}
Or even:
boolean dealerExists(String id) {
return (fetchDealer(loginId) != null);
}
This would allow for better logical flow of your code. Your if statement would be very clear then:
if(DealerFactory.dealerExists(loginId) {
throw new Exception("Sorry That Dealer Already Exists");
}
Also, the value DNo is the dealer number I presume and you are checking if a dealer exists with the provided loginId or the provided DNo. However, in you checks you are comparing the DNo to the loginId to check if a dealer exists. What exactly is the point of DNo and shouldn't the loginId be enough to determine that the dealer exists?
If you really need to check the DNo as well, just add it as a check within the methods I suggested above.
More information regrading the variables that you are passing into the conditional would be of great help, (i.e. loginId and DNo). The first thing I would do is simplify your conditions in the if & else if statements.
It seems like you could change the if conditional to be if(DealerFactory.fetchDealer(loginId)) and have it work just the same since if the factory returns a dealer with the ID that you are looking for, that dealer already exists. From my understanding of what you're trying to achieve, it's unnecessary to dig any deeper. Also try running through this section of code with the debugger and monitor variables step-by-step to see what things look like at each line of code.
Edit:
You could also move the expressions outside of the conditional and set them to variables. For example:
int dealerId = DealerFactory.fetchDealer(loginId);
if(dealerId != null && dealerId != loginId) {
//<< proceed with the rest of the method here >>
} else {
//<<throw exception>>
}
Checking to see if dealerId is null in the conditional would avoid NullPointerExceptions, and declaring things outside of the conditional will make it easier to debug by hand.
Related
I have seen two common ways
one checks return like this
int returnCount = userMapper.insert(user);
if (returnCount == 0) {
return "insert fails";
}
another way checks if function throws exception
try {
userMapper.insert(user);
} catch (Exception e) {
return "insert fails";
}
Actually, it also confused me when I study PrepareStatement executeUpdate method in JDBC.
In my view, if a method like that executed successfully, it returns a int value(no matter if it equals zero),or it will throw exception, but I'm not sure for that.
Thanks for the comment above, I just figured it out.I read some other blogs and thought about the comment carefully.Actually, success is a very subjective concept. A statement may execute normally(which means no exception thrown), it also can be unsuccess if the result does not meet our expectation(like updating a record that we thought existed but did not actually exist).That's why we check returns.
Hi everyone this is my first question so I apologies if this has been answered somewhere before but I couldn't find an answer to the question so I'm posting it here.
In the case where your method has a return value that can be positive or negative, and you are unsure of the range the return value, what value should you return if you get an exception?
For example in the method below-
public double calculateDifference(String studentName, String quizName) {
try {
Quiz quiz = quizDAO.retrieve(quizName);
double averageScore = quiz.getAverageScore();
Student student = quiz.getStudent(studentName);
double score = student.getScore();
return score - averageScore;
} catch (NullPointerException e) {
return -1;
}
}
Assuming score and average score have a large range, what if my return value in my catch is equal to the value returned when there is no exception?
For example, score=2, and average score=3, so I will get -1 as a return value.
When I get that return value I'm unsure of whether an exception was caught or not.
What I'm asking I guess is if there is a way, when caught, to return a unique double value that doesn't clash with other possible return values.
Simple: NullPointerExceptions are bugs.
You do not catch them.
You debug them to understand their cause, and then you fix the problem. End of story.
Yes, when you have a really huge application, then your top layer can catch on RuntimeException - but only to log that information and give a somehow helpful message to your user.
Yes, there are certain RuntimeExceptions that you can catch, for example NumberFormatException when parsing input strings that are supposed to be numbers. But as said, catching NPE to return -1 is simply wrong. It hides an error condition and makes it close to impossible to predict how your code will continue from there.
In your specific case: simply make sure that you do not invoke the method with null arguments. Or, if you really want to allow passing null arguments, you can put something like
Objects.requireNonNull(var, "var must not be null)
in the first lines of your method (one check for each parameter that might be null). Then you make it at least explicit that passing null will make the method throw an npe, even with a nice clear error message.
Instead of catching the NullPointerException within the calculateDifference() method. It would perhaps be better to declare that the method throws an some exception, so that the user of the method is aware that something can go wrong.
Maybe you should consider using IllegalArgumentException, and doing a check for null values in your method.
public double calculateDifference(String studentName, String quizName)
throws IllegalArgumentException {
Quiz quiz = quizDAO.retrieve(quizName);
if(quiz == null)
throw new IllegalArgumentException("There is no such quiz!");
double averageScore = quiz.getAverageScore();
Student student = quiz.getStudent(studentName);
double score = student.getScore();
return score - averageScore;
}
However, the downside of using RuntimeExceptions like NullPointerException and IllegalArgumentException is that even though they are declared as thrown by the method, they are not enforced, so the caller doesn't have to catch them at all. Therefore, if you are willing to go to the trouble of writing your own subclass of Exception, it would be best to throw this, since then the user of the method will have to handle the exception.
You should not catch NullpointerException according to Effective Java book. It's usually a programming mistake. Also see here: Should I always not catch NullPointerException?
I would do:
public double calculateDifference(String studentName, String quizName)
{
if (studentName == null || quizName == null){
throw new IllegalArgumentException("Student name: " + studentName + ", quizName: " + quizName);
}
Quiz quiz = quizDAO.retrieve(quizName);
double averageScore = quiz.getAverageScore();
Student student = quiz.getStudent(studentName);
double score = student.getScore();
return score - averageScore;
}
I've got a MVC based Java application with three models: Room, Student and StudentRoom.
StudentRoom contains an object of Room and Student.
Now I've got the problem that if my SQL query returns no result and I check the value of student's name like this
if(studentRoom.student.name != null) {
}
I'll get a NullPointerException and I don't know how to handle it.
Should I set Student.name = ""; since my query has no result?
if(studentRoom != null && studentRoom.student != null && studentRoom.student.name != null){
//.. Access student
}
Above solution looks a bit weird. you should better use getter/setter methods instead of directly accessing the objects.
Apart from that you can define methods like isStudentAvailable() in studentRoom to check whether it has Student in it or not.
Should I set Student.name = ""; since my query has no result ?
It completely depends on your use case. But I must say better to keep it null as it will raise the exception instead of passing the null check validations.
You might need a try/catch statement for that. Something like this :
try {
// do process here
} catch (NullPointerException npe) {
//to do if student is null
}
But take note, if there are any object that is inside the try statement, a NullPointerException would still be thrown. Hope this helps.
So I don't want to avoid an IndexOutofBounds error; however, I want to know how to know when one hits it without crashing the program.
List<String> pool = new ArrayList<>();
pool.add("a");
boolean checked = (pool.get(1) == null); //I know this doensn't work
System.out.println(checked); //I want false
So in this example it is obvious that nothing exists in index 1 of my List pool. Is it possible to get a boolean value for this? Or is it possible to check if the end of a list has been reached without doing i < list.size()? Thanks for your time and help.
It's called a try-catch block:
boolean hasValue;
try {
hasValue = (pool.get(i) != null);
} catch (IndexOutOfBoundsException e) {
hasValue = false;
}
// hasValue == true if non-null value found at index i
However this is an anti-pattern called "exceptions as flow control".
The answer is no. You can check the docs and see that other than checking the size there is no way to "fetch if exists" or to find if "does index exist".
Trying to access the index and catching the exception is possible but not recommended because catching exceptions is an expensive operation in java
I've been struggling to find why my if statement didnt work properly so I used a try catch block instead. This is the if statement as I had it:
//selectArtistByName returns an Artist object
if (!selectArtistByName(artist.getName()).equals(artist.getName()) ||
selectArtistByName(artist.getName())==null) {
//save data to database
}
When I ran the above, I got a NullPointerException because the method selectArtistByName was returning null as the database was empty. What I don't understand is why it didn't go in the if statement when I was getting null. So I did this and it worked:
try {
if (!selectArtistByName(artist.getName()).equals(artist.getName())) {
}
} catch (NullPointerException e) {
m_db.insert(TABLE_ARTIST, null, artistContents);
}
I'm not a Java guru but it looks like a horrible fix to me. How could I fix this.
You just need to change the order of condition in if block:
if (selectArtistByName(artist.getName()) == null ||
!selectArtistByName(artist.getName()).equals(artist.getName())) {
//save data to database
}
Do the null check first.
If that succeeds, then 2nd condition is not evaluated, and hence no NullPointerException. This is how short-circuit OR operator works. It only evaluates the 2nd expression, if 1st one evaluates to false.
If null check fails, then 2nd condition is evaluated, which wouldn't throw NPE, as it has already been confirmed by first condition.
Also, as rightly pointed out by #ruakh in comment, your condition seems to be broken. selectArtistByName sounds to be returning an Artist, which you can't compare with String.
I guess, you don't even need the 2nd condition. I would assume, selectArtistByName() method has already done the equality check for name, based on which it will return Artist. Just check that selectArtistByName method return null, that would be enough. So, you should change the if block to:
if (selectArtistByName(artist.getName()) == null) {
//save data to database
}
Just put the null condition check at the beginning to shortcut when artist is unknown:
if (selectArtistByName(artist.getName())==null || !selectArtistByName(artist.getName()).equals(artist.getName())) {
//save data to database
}
You can find more info about lazy evaluation in this other question: Does Java have lazy evaluation?