Why doesn't this if-statement short circuit? - java

I'm currently fixing a bug in someone else's Java code, but I cannot explain the bug. The code in question is the following if-statement:
if (locked && DEBUG_ENABLED
&& owner != null
&& (owner.equals(playerName) || subowner.equals(playerName))
&& handleCommand(playerName, message)) {
....
} else {
....
}
In which DEBUG_ENABLED is initialized as private static boolean DEBUG_ENABLED = false; and handleCommand functions like this:
public boolean handleCommand(String name, String msg) {
if(msg.equals("Command1")) {
....
} else if(msg.equals("Command2")) {
....
} ....
} else { // No matching command
return false;
}
return true;
}
What puzzles me is that even though DEBUG_ENABLED is set to false, the code still calls and executes the handleCommand function. I always thought this wasn't supposed to happen due to short circuiting.
The if-statement itself in total is still evaluated as false, since only the code inside the else-block in the first snippet is executed.
So, how come this if-statement is behaving like this? Is it failing to short-circuit, or do I misunderstand the principle, or is there something completely different wrong with this part of code? (Besides the missing null check for subowner that is, which is done outside of this part.)

It is not possible that the && operator fails to short-circuit. Were you using & perhaps? If not it means you have made some false assumptions that previous conditions before the last one were false.

Related

Is using the order of evaluation to check for null values bad practice?

If I wish to perform two checks on a string, that it is not null, and that it is not 0 length, I could do this-
if(string != null) {
if(string.length() > 0) {
//Do something
}
}
Or I could do this
if(string != null && string.length() > 0) {
//Do something
}
As the first check is executed first, the second comparison doesn't happen and a NullPointerException isn't thrown.
Is the second method guaranteed to work in all cases? And if so, would it be considered bad practice to use it?
No, it is perfectly fine and guaranteed to work in all cases.
Reference from Java specification: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.7
The one worth mentioning here: as you write such checks very often, it is advisable to put them into some dedicated helper method; such as:
static boolean doesStringContentContent(String value) {
or something alike.
And from an "improved" readability perspective, you might prefer coding that like
if (value == null) return false;
if (value.isEmpty()) return false;
return true;
But that doesn't matter too much - the important part is that you should not start copying around this check.
And finally, the one other possibility would to not return a boolean, but to have a
void checkStringHasContent(String value) {
which could throw a NullPointerException resp. some other thingy for an empty string.
you are using && (and) operator in second expression. and nested if condition in first expression. in both cases you will get same result. because &&(and) operator execute second condition if only if first condition is true.
basically you are doing same thing in different manner.

Trying to come up with solution using recursion

I know there are multiple ways to find out if a word is palindromic, like using the reverse function of StringBuilder or even the reverse function of Collections, but in an attempt to learn recursion, I wrote it this way. I even had it working iteratively.
I kind of added return true in my embedded else statement, but I'm really not sure what to do, because when I run this in debug mode, it returns false, then invokes checkPalindrome again, which I don't understand why, because it should return and terminate, no? I would really appreciate an explanation of what I'm doing wrong and how to get it working this way.
public static boolean checkPalindrome(Deque deq) {
if(deq.pollFirst() != deq.pollLast()) {
return false;
} else {
if(deq.size() == 1 || deq.size() == 0) {
return true;
} else {
checkPalindrome(deq);
return true // TODO ?? figure out What to put here ??
}
}
}
It's that you are not returning anything when you call yourself. The inner else statement should read this:
else {
return checkPalindrome(deq);
}
You have a followup question in the comments below that leads me to want to explain how recursive methods work, but in essence, they all follow the following pseudo-code:
public boolean someMethod(T[] someArrayOrList) {
// return true -OR-
// return false -OR-
// call yourself and return whatever that call returns
}
No matter what, when you call the method it will return SOMETHING... Either it will return something itself, or it will return whatever some other call of itself will return. In a way it is AND'ing all the responses, but in reality TRUE is only generated once.

Is there any method in java which does the same thing as isset() in php?

Basically I have a if..else logic as below
if(request.getParameter("action")=="delete" && request.getParameter("action")!=null)
{
//delete operation
}
else
{
//update operation
}
But during update process "action" parameter do not get attached with URL and hence NullPoitnerException is thrown.
Any solution to fix it?
Thanks in advance!
If your request.getParameter(x) returns null when x is not set, you could simply swap the two conditions in your if-clause.
Thus
if(request.getParameter("action")=="delete" && request.getParameter("action")!=null)
would become
if(request.getParameter("action")!=null && request.getParameter("action")=="delete")
Since && is a short-circuit Boolean And in Java, this will cause the the second half of the statement to be executed only if the part before the && evaluates to true - thereby preventing your NullPointerException.
request.getParameter("action")=="delete" is a comparison with a string literal, though. You are most likely better off using .equals() instead.
In Java 8 you can do like this
Optional<String> paramOptional=Optional.ofNullable(request.getParameter());
paramOptional.ifPresent(param->{
//Do something with param
});
OR
String param =paramOptional.orElse("you else string");//if null then this string will be return

what does Dead Code mean under Eclipse IDE Problems Section

I am using Eclipse Helios IDE for our Web Application development.
Under Problems section in Eclipse, for some of lines the description is displayed as "Dead Code".
Could anybody please tell me what does Dead Code actually mean ?
Please see the screen shot for your reference.
For example this part is shown as dead code under Eclipse
else {
int length;
if (ar != null)
length = Array.getLength(ar);
else
length = 0; // This line is dead code
In Eclipse, "dead code" is code that will never be executed. Usually it's in a conditional branch that logically will never be entered.
A trivial example would be the following:
boolean x = true;
if (x) {
// do something
} else {
// this is dead code!
}
It's not an error, because it's still valid java, but it's a useful warning, especially if the logical conditions are complex, and where it may not be intuitively obvious that the code will never be executed.
In your specific example, Eclipse has calculated that ar will always be non-null, and so the else length = 0 branch will never be executed.
And yes, it's possible that Eclipse is wrong, but it's much more likely that it's not.
Dead code is code that will never be executed, e.g.
boolean b = true
if (!b) {
....
// dead code here
}
Dead code means, that there is no way that this code will be executed.
Sometimes you even can't compile it (like this case:)
private Boolean dead_code()
{
return true;
//Dead code below:
dosomething();
}
But in other cases this is not too obvious, eg this statement:
b=true;
[...]
if (b==false)
{
//Dead code
}
If you have this message, there is some major flaw in your code. You have to find it, otherwise your app won't work as intended.
There are two kinds of diagnostics that Eclipse gives out for marking code that will/may not be executed at runtime.
1) Unreachable code: These are the usual java warnings that follow the unreachability rules of the JLS, and are also given by javac. These are meant to be compile errors. Examples:
int foo() {
return 1;
int i = 1; // Unreachable
}
int foo2() {
while (true);
int i =1; //Unreachable
}
There are other more complicated examples :)
2) Dead code: This is Eclipse's own static analysis warnings, and are mostly tied out of the null analysis i.e.
void foo() {
Object o = null;
if (o == null) {
} else {
// dead code
}
The examples given above should NOT give a dead code warning. i.e.
boolean x = true;
if (x) {
// do something
} else {
// this is dead code!
}
should not give the warning, because JLS forbids the compiler to evaluate the 'value' of variables. All that we can evaluate is the 'nullness'
Hope this helps
You might be having an Null pointer exception in the lines above the "Dead Code" lines.
Make sure you check for "Null Pointer" exception.
It is possible that you have used the variable ar before. Then the compiler knows that the line in the else statement will never be executed. Either there will be a NullPointerException at the place where you used ar or the first part of the if statement will be executed.
let me give some answer for the dead code.
Eg:
public class UnreachableTest{
public static void main(){
try{
// some code
}
catch(Exception exc){
throw new NullPointerException();
System.out.println("Unreachable line"); // compile time error
}
}
}
here the System.out.println("Unreachable line"); is never executed.
Which in turn considered to be a dead code.
Another example may be:
int func(int i, int j)
{
int sum = i + j;
return i + j; // never actually using the sum
}
simple the function returns i + j; never really uses sum.
Sum is considered to be dead code here.
Some other case when this happens.
System.out.println("result :" + result + ":" + result.isEmpty());
if (result == null)
return result;
else if(!result.isEmpty())
str.append(result + " ");
1) Here as you you are printing result and checking isEmpty() eclipse assumes that result is not null so it will not go in if. So return result is dead code.
2)Now let say result is coming null so you will get NullPointerException in result.isEmpty() so again it will not go in if and return result is deadcode
To make this work just comment out System.out.println().
Eclipse gives this warning if the condition check you are giving may never be satisfied. Following are some examples
Object o=null;
if(o!=null) {
//Some code
}
Here Dead code warning will come as Object is already made null
Another example is given below
BSTTest bstTest=null;
bstTest.test=10;
if(bstTest==null) {
//some code
}
Here the code is trying to access a variable of the class. As the variable is already accessed, eclipse will give dead code warning in if(bstTest==null) as bstTest may not be null when the variable is already accessed.
Note: Here bstTest.test will give null pointer exception
Simple Example of Dead Code
public class IfTest {
public static void main(String[] args) {
if (true) {
if(false) {
System.out.println("a"); //Dead code, Never be Execute this if block.
}else {
System.out.println("b");
}
}
}
To simplify the term's Unreachable code and dead code:
Unreachable Code is a code block/statement in Java to which the control never reaches and never gets executed during the lifetime of the program. Following is the example of unreachable code. This generates compiler time error.
public void unreachableCodeExample() {
System.out.println("This will execute");
return;
System.out.println("This will not"); //This is Unreachable code
}
While A Dead code is an unreachable code, but it doesn’t generate compile time error. But if you execute it in eclipse (Or some other IDE) it gives you a warning. See below example,
public void deadCodeExample() {
if (true) {
System.out.println("This will execute");
return;
}
System.out.println("This will not"); //This is dead code
}
Dead code is the section of our code that is never going to execute runtime, its useless
EX:
if(false){ // statements }
For more example u can refer : DeadCode Examples
Try this:
while (true) {
if(false == true) break;
}
S.O.P("I will never reach here!") <-- This code will never be executed.
The code is valid as it conform to the compiler, however in reality the loop will never exit, and in effect S.O.P will never be executed.

Java comparing enumerator (Strange behaviour)

I work with a Java project and Eclipse(Version 3.6.2) as IDE, in a enum comparison i get a strange behaviour, following an example of the weirdness :
Global Variable :
StatusType status = StatusType.SIGNATURE;
Code :
String trsStatus = "END";
if(trsStatus.equals("END") && (this.status.compareTo(StatusType.SIGNATURE) != 0)){
//Do something
}
This comparison succeeds and enter in the if block, Why ? In this case the second evaluation(this.status.compareTo(StatusType.SIGNATURE) != 0) of the if statements fail because the result is false ! Why java however enter in the block ???
If i evaluate the expression on the expression watcher of eclipse debugger the value of the statements are :
trsStatus.equals("END") ---> true
(this.status.compareTo(StatusType.SIGNATURE) != 0) ---> false
I've done another test, if i assign the result of the second expression in the if statements to a boolean variable :
boolean sign = (this.status.compareTo(StatusType.SIGNATURE) != 0);
i get this result :
(this.status.compareTo(StatusType.SIGNATURE) != 0) ---> false
sign ---> true
Why ?!?
How this can be possible ?
Could it be that StatusType overrides compareTo() in some weird way?
Are there any other threads that could be changing the value of the status field?
In any case, you should use equals() or even == rather than compareTo() here.
this.status.compareTo(StatusType.SIGNATURE) != 0 will return zero, because zero means they are equal. compareTo() returns either 1, -1, or 0, based on which value is considered greater.
The only sensible reason I could imagine is that
this.status != StatusType.SIGNATURE
Period. You probably set status to some other value unknowingly. Maybe with another thread. Who knows. What does status evaluate to, in your debugger?
In any case, there is certainly no such "bug" in Java. Unless you post some more code that proves it ;-)
You should use: this.status != StatusType.SIGNATURE.
public class Test {
public static void main(String[] args) {
TestEnum e = TestEnum.SIGNATURE;
System.out.println(e.compareTo(TestEnum.SIGNATURE));
String test = "test";
if (test.equals("test") && e.compareTo(TestEnum.SIGNATURE) != 0) {
System.out.println("I'm here");
}
}
}
I did the following test. It does not enter the if block and print "I'm here".
Can you post your snippet?

Categories

Resources