I'm writing an android app that does a lot of stuff. I recently refactored my code to have a better structure, but suddenly I'm getting a very strange problem.
handleRequest(String str)
{
boolean foo = executeCommand(str);
this.publishProgress("FOO1: " + foo);
if (foo == false);
{
this.publishProgress("FOO2: " + foo);
sendString("Failed to execute: " + str);
}
this.publishProgress("FOO3: " + foo);
sendEOM();
}
The code above should execute a command, and store 'foo' with if the command was executed correctly. This code is inside an Android AsyncTask (thread) so I use 'publishProgress' to show a toast.
I've been flipping through the debugger and FOO is true! The toasts show FOO to be true the entire way through as well. However, it goes ahead and jumps inside the IF block and executes that too. I've never seen this before, I think its a problem with Java. I was stepping though the function 'executeCommand' and it looks like it is skipping return statements too.
I've ran the code on a virtual device and a real one and they both do this.
Any ideas? I'm completely at a loss here.
You said
if (foo == false);
remove the semicolon, it should be
if (foo == false) {//your code}
Remove the semicolon: if (foo == false); -> if (foo == false)
You put a semicolon after if statement.
That way, your if statement is there on its own, and the following block of code is always running.
Modify your code like this:
handleRequest(String str) {
boolean foo = executeCommand(str);
this.publishProgress("FOO1: " + foo);
if (foo == false) {
this.publishProgress("FOO2: " + foo);
sendString("Failed to execute: " + str);
}
this.publishProgress("FOO3: " + foo);
sendEOM();
}
N.B.
Keeping your block-opening braces in the same line as the function definition/loop condition makes these kinds of mistakes much less frequent, IMO.
There will be no ";" semicolon after if statement.
So instead of if (foo == false); it should be if (foo == false){}
If you write semicolon (;) after if statement it ends the if condition there!
you need to start a block of code after writing if condition i.e.
if(foo == false){
// block of Code
} //end of if condition
I don't know how this line compiles if (foo == false);, but evidently it does. You need to remove the semicolon at the end of the line as others have mentioned. With the ; there it means do nothing if foo is false. Then the program goes into the next block between the two curly braces.
You need to install findbugs or PMD to warn against this kind of typos.
Related
I'm a beginner in coding. I was recently working with to create a chatting programme where a user will chat with my computer. Here is a part of the code:
System.out.println("Hello, what's our name? My name is " + answer4);
String a = scanner1.nextLine();
System.out.println("Ok, Hello, " + a + ", how was your day, good or bad?");
String b = scanner2.nextLine();
**if (b.equals("good"))** { //1
System.out.println("Thank goodness");
} else **if (b.equals("it was good"))** { //2
System.out.println("Thank goodness");
} else **if (b.equals("bad"))** { //3
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
} else **if (b.equals("it was bad"))**{ //4
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
if(age<18){System.out.println("How was school?");}
else if (age>=18){System.out.println("How was work?");}
The conditions of the if statements are in Bold (surrounded with **). In case of first and the second condition I want my application to do same thing. Similarly third and fourth condition. I thought it was possible to somehow group them in if statement.
I tried with below code but it doesn't compile:
if (b.equals("good"), b.equals("it was good")) {
System.out.println("Thank goodness");
} else if (b.equals("bad"),(b.equals("it was bad"))) {
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
Can someone correct it for me?
You can use logical operators to combine your boolean expressions.
&& is a logical and (both conditions need to be true)
|| is a logical or (at least one condition needs to be true)
^ is a xor (exactly one condition needs to be true)
(== compares objects by identity)
For example:
if (firstCondition && (secondCondition || thirdCondition)) {
...
}
There are also bitwise operators:
& is a bitwise and
| is a bitwise or
^ is a xor
They are mainly used when operating with bits and bytes. However there is another difference, let's take again a look at this expression:
firstCondition && (secondCondition || thirdCondition)
If you use the logical operators and firstCondition evaluates to false then Java will not compute the second or third condition as the result of the whole logical expression is already known to be false. However if you use the bitwise operators then Java will not stop and continue computing everything:
firstCondition & (secondCondition | thirdCondition)
Here are some common symbols used in everyday language and their programming analogues:
"," usually refers to "and" in everyday language. Thus, this would translate to the AND operator, &&, in Java.
"/" usually refers to "or" in everyday language. Thus, this would translate to the OR operator, ||, in Java.
"XOR" is simply "x || y but both cannot be true at the same time". This translates to x ^ y in Java.
In your code, you probably meant to use "or" (you just used the incorrect "incorrect solution" :p), so you should use "||" in the second code block for it to become identical to the first code block.
Hope this helped :)
You're looking for the "OR" operator - which is normally represented by a double pipe: ||
if (b.equals("good") || b.equals("it was good")) {
System.out.println("Thank goodness");
} else if (b.equals("bad") || b.equals("it was bad")) {
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
This is probably more answer than you need at this point. But, as several others already point out, you need the OR operator "||". There are a couple of points that nobody else has mentioned:
1) If (b.equals("good") || b.equals("it was good")) <-- If "b" is null here, you'll get a null pointer exception (NPE). If you are genuinely looking at hard-coded values, like you are here, then you can reverse the comparison. E.g.
if ("good".equals(b) || "it was good".equals(b))
The advantage of doing it this way is that the logic is precisely the same, but you'll never get an NPE, and the logic will work just how you expect.
2) Java uses "short-circuit" testing. Which in lay-terms means that Java stops testing conditions once it's sure of the result, even if all the conditions have not yet been tested. E.g.:
if((b != null) && (b.equals("good") || b.equals("it was good")))
You will not get an NPE in the code above because of short-circuit nature. If "b" is null, Java can be assured that no matter what the results of the next conditions, the answer will always be false. So it doesn't bother performing those tests.
Again, that's probably more information than you're prepared to deal with at this stage, but at some point in the near future the NPE of your test will bite you. :)
You can have two conditions if you use the double bars(||). They mean "Or". That means only ONE of your conditions has to be true for the loop to execute.
Something like this:
if(condition || otherCondition || anotherCondition) {
//code here
If you want all of conditions to be true use &&. This means that ALL conditions must be true in order for the loop to execute. if any one of them is false the loop will not execute.
Something like this:
if(condition && otherCondition && anotherCondition) {
//code here
You can also group conditions, if you want certain pairs of them to be true. something like:
if(condition || (otherCondition && anotherCondition)) {
//code here
There is a simpler way.
if (b.contains("good")) {
...
}
else if (b.contains("bad")) {
...
}
I have a lot of java files wherein I have to search for a method, if present I have to add a line inside this method "If this line does not already exist". This line has to be added before the closing brace of the method.
So far I have the following code:
import os
import ntpath
extensions = set(['.java','.kt'])
for subdir, dirs, files in os.walk("/src/main"):
for file in files:
filepath = subdir + os.sep + file
extension = os.path.splitext(filepath)[1]
if extension in extensions:
if 'onCreate(' in open(filepath).read():
print (ntpath.basename(filepath))
if 'onPause' in open (filepath).read():
print ("is Activity and contains onPause\n")
#Check if Config.pauseCollectingLifecycleData(); is in this code bloack, if exists do nothing, if does not exist add to the end of code block before }
if 'onResume' in open (filepath).read():
print ("is Activity and contains onResume\n")
#Check if Config.resumeCollectingLifecycleData(); is in this code bloack, if exists do nothing, if does not exist add to the end of code block before }
But I am not sure where to go from here, Python not being my first language. Could I request to be guided in the right direction.
Example:
I am looking for a method with the following signature:
public void onPause(){
super.onPause();
// Add my line here
}
public void onPause(){
super.onPause();
Config.pauseCollectingLifecycleData(); // Line exists do nothing
}
This is actually quite difficult. First of all, your if "onPause" in sourcecode approach currently doesn't distinguish between defining onPause() and calling it. And second of all, finding the correct closing } isn't trivial. Naively, you might just count opening and closing curlies ({ increments the blocklevel, } decrements it), and assume that the } that makes the blocklevel zero is the closing curly of the method. However, this might be wrong! Because the method might contain some string literal containing (possibly unbalanced) curlies. Or comments with curlies. This would mess up the blocklevel count.
To do this properly, you would have to build an actual Java parser. That's a lot of work, even when using libraries such as tatsu.
If you're fine with a rather volatile kludge, you can try and use the blocklevel count mentioned above together with the indentation as a clue (assuming your source code is decently indented). Here's something I've hacked up as a starting point:
def augment_function(sourcecode, function, line_to_insert):
in_function = False
blocklevel = 0
insert_before = None
source = sourcecode.split("\n")
for line_no, line in enumerate(source):
if in_function:
if "{" in line:
blocklevel += 1
if "}" in line:
blocklevel -= 1
if blocklevel == 0:
insert_before = line_no
indent = len(line) - len(line.lstrip(" ")) + 4 #4=your indent level
break
elif function in line and "public " in line:
in_function = True
if "{" in line:
blocklevel += 1
if insert_before:
source.insert(insert_before, " "*indent + line_to_insert)
return "\n".join(source)
# test code:
java_code = """class Foo {
private int foo;
public void main(String[] args) {
foo = 1;
}
public void setFoo(int f)
{
foo = f;
}
public int getFoo(int f) {
return foo;
}
}
"""
print(augment_function(java_code, "setFoo", "log.debug(\"setFoo\")"))
Note that this is vulnerable to all sorts of edge cases (such as { in a string or in a comment, or tab indent instead of space, or possibly a thousand other things). This is just a starting point for you.
I have a problem where .contains() is not returning true when looking for a substring.
See the below code snippet and image which shows variable values for the following code. The problem I have is that the expression returns false, when I think it should obviously be true.
if (this.fileName.toLowerCase().contains(extension.toLowerCase())){
return true;
}
I have encountered this today, after searching the web I can't see anything obvious that is going on here.
I have tried the same using literals, but still does not evaluate to true:
if ("Android App Image.jpg".toLowerCase().contains("jpg".toLowerCase())){
return true;
}
I have broken it down further so the result is in a boolean:
boolean result = ("Android App Image.jpg".contains("jpg"));
if (result) {
return true;
}
The result is true, so .contains is not the issue, rather it appears my if() doesn't evaluate the boolean as true and doesn't cause return true to execute.
I now think it's an issue with my while loop (full function below). Does the enumeration run asynchronously?
public boolean isImage(){
String[] imageExtensions = {"jpg", "png", "bmp", "gif"};
for (String extension: imageExtensions) {
if (this.localFileURLString != null && this.localFileURLString.toLowerCase().contains(extension)){
return true;
}
boolean result = ("Android App Image.jpg".toLowerCase().contains("jpg".toLowerCase()));
if (result) {
return true;
}else{
Log.i("TEACH", "If evaluated false");
}
}
return false;
}
UPDATE 1/2:
I have trimmed down the entire function, with hard coded literals and no longer using fast enumeration, which still returns false when I expect it to return true:
public boolean isImage(){
String[] imageExtensions = {"jpg", "png", "bmp", "gif"};
for (int x = 0; x < imageExtensions.length; x++) {
// String extension = imageExtensions[x];
boolean result = ("Android App Image.jpg".toLowerCase().contains("jpg".toLowerCase()));
if (result) {
return true;
}else{
Log.i("TEACH", "If evaluated false");
}
}
return false;
}
The function does not returns true or does the "If evaluated false" Log get executed, it just jumps straight to the last line of the function (return false;) after evaluating the line if (result) {... it's as if the if breaks the loop.
UPDATE 2/2:
Quite simply, even the most simple of if statements inside my function would cause the code to jump to the last line of the function and return false. For example:
if(true == true){
return true
}
This happened when stepping through in debug mode and also coded logs show the same result when not attached to a bugger.
After returning from the function every carries on as normal. No errors or warnings.
re-installing Android Studio, trying different simulators and physical Android devices didn't resolve the issue.
Renaming the function didn't resolve the issue.
Changing the return type of the function from boolean to Boolean did resolve the issue.
I'm well aware of the differences in these types, but I'm still perplexed as to to why this would this this problem. I can only assume changing the method signature in this way solved is something funky was happening at compile time.
I'll leave the question open for now, as even though changing the return type "fixed" the issue for me, i'm still not satisfied i'll know why... probably never will.
Hopefully somebody much more knowledgable on these sorts of issues can enlighten is all!
Why don't you try using:
if (this.fileName.toLowerCase().contains(extension.toLowerCase()==true){
}
Your search term produces false positive . Cause the file name string can have a substring that matches the extension.
To avoid this you can prepend the search terms by a dot.
String[] imageExtensions = {".jpg", ".png", ".bmp", ".gif"};
This will apperantly solve your problem .
It can produce false positive if there's any irregular use of DOT in the file name.
Hope it helps.
How does the Java compiler, and other compilers, handle the following scenario; where there is a nested if with no curly brackets?
// In Java, to which of the 'if's does this 'else' belong?
// If bOne=false and bTwo=true, will the println run?
boolean bOne = false;
boolean bTwo = true;
if (bOne)
if (bTwo)
bTwo = bTwo; // do nothing
else
System.out.println("bOne:" + bOne + ". bTwo:" + bTwo);
The else clause applies to the second if statement. At first, it should be read as:
if (bOne)
if (bTwo)
bTwo = bTwo; // do nothing
else
System.out.println("bOne:" + bOne + ". bTwo:" + bTwo);
And then the code should be rewritten to use curly braces.
This applies to many imperative programming languages, one notable exception being Python which has significant indentation instead of curly braces.
This is known as the dangling else problem. The rule that solves this is that the else belongs to the closest if. So in that example, the else belongs to if (bTwo).
It does, as some others have already said, belong to the "nearest preceding if". However, to AVOID this problem always use braces (and proper indentation), so that there's no need to try to figure this out by understanding how the compiler works.
By the way, the compiler solves this in this way (pseudo-code):
process_if()
{
expect_token("if");
next_token();
expect_token("(");
next_token();
condition = parse_expression();
expect_token(")");
next_token();
then_part = parse_statement_or_block();
if (current_token == "else")
else_part = parse_statement_or_block();
else
else_part = nothing;
}
parse_statement_or_block()
{
if (current_token() == "{")
do
{
statements += parse_statement();
} while(current_token() != "}");
else
statements = parse_statement();
}
parse_statement()
{
switch(current_token())
{
case "while":
process_while();
break;
case "for":
process_for();
break;
case "if":
process_if();
break;
....
}
}
The way this parser works is that it reads the first if, and the statement inside that is another if, so it goes to process_if, takes the condition, the then_part and then checks for an else and takes that as the else_part for that if. Then goes back to the first if-statement and finds "no else there" (because it has already been consumed).
Actual compiler code that does exactly this:
https://github.com/Leporacanthicus/lacsap/blob/master/parser.cpp#L1854
I've written the following if-statement in Java:
if(methodName.equals("set" + this.name) ||
isBoolean() ? methodName.equals("is" + this.name) :
methodName.equals("get" + this.name)) {
...
}
Is this a good practice to write such expressions in if, to separate state from condition? And can this expression be simplified?
I would change it to
if (methodName.equals("set" + this.name)
|| methodName.equals( (isBoolean() ? "is" : "get") + this.name)) {
...
}
Is it good practice? It's good if it makes it easier to read. It makes it easier to read if (1) it does and (2) the sort of person who'd be confused by it won't be reading it. Who's going to read it?
Wouldn't something like the following work?
if (methodName.equals("set" + this.name)
|| methodName.equals("get" + this.name)
|| (isBoolean() && methodName.equals("is" + this.name))) {
...
}
It's more readable than the way in which you used the ternary operator and certainly easier to understand. It also has the advantage that it can avoid an unnecessary method call to the isBoolean method (it has either 1, 2 or 4 method calls whereas yours always has either 1 or 3; the performance gain/loss is probably too minute to notice).
Also there's a similar question here titled "Is this a reasonable use of the ternary operator?" One user had the following to say:
The ternary operator is meant to
return a value.
IMO, it should not mutate state, and
the return value should be used.
In the other case, use if statements.
If statements are meant to execute
code blocs.
Do note that I included parentheses around the expression containing '&&' for readability. They aren't necessary because x && y is evaluated before m || n.
Whether you choose to use it is up to you, but I tend to avoid it in favour of readability.
I would be inclined to change it to
if (methodName.equals(setterForThis())
|| methodName.equals(getterForThis())) {
...
}
with some functions extracted:
private String setterForThis() {
return "set" + this.name;
}
private String getterForThis() {
return (isBoolean() ? "is" : "get") + this.name;
}
It's longer of course, but I'm not really into golf anyway.