Is there a feature that lets me check on which path the variable for which I'm getting a "might not be initialised" error is supposedly not initialised? Preferably either native to Java or built into Intellij?
EDIT: managed to reduce my code to a minimal failing example
class MyFailure{
public static void main (String[] args) throws java.lang.Exception{
String test;
boolean abort = false;
while(!abort){
if(false){
abort = true;
continue;
}
test = "stupid";
if(test.equals("stupid")) break;
}
if(!abort){
System.out.println(test);
}
}
}
Main.java:21: error: variable test might not have been initialized
Suppose the while loop reads from a server socket until the buffered value satisfies a certain condition and the if(false) is in fact a check whether the client closed the connection, how would you suggest I handle this?
For the code in your question there is a fairly straightforward solution: use the variable inside the loop where Java too can see it has a value:
public static void main (String[] args) throws java.lang.Exception{
boolean abort = false;
while (!abort){
if (false) {
abort = true;
continue;
}
String test = "stupid";
if (test.equals("stupid")) {
System.out.println(test);
break;
}
}
}
Whether this will work in your real-life code I cannot tell. Consider extracting a method for dealing with the value obtained from the socket and call it from where the System.out.println() is in the example.
Edit: For what it’s worth, the following version compiles too. You may still think that the use of the value (the println) is so deeply nested it reduces readability:
public static void main (String[] args) {
if (! isFalse()) {
String test;
do {
test = "stupid";
} while (! isFalse() && ! test.equals("stupid"));
if (! isFalse()) { // connection still open, so not aborted
System.out.println(test);
}
}
}
private static boolean isFalse() {
return false;
}
As mentioned in the comments I do sometimes — hesitatingly — resort to initializing the variable in question with a nonsensical/bogus value in the declaration so that if that value ever gets used because of a programming error, I will discover. In your example I might use null:
String test = null;
And after the loop:
assert test != null;
so I will catch if it didn’t get a proper value. It’s not a solution I’m happy with, but it happens that I cannot find anything better.
Related
I thought the default value of boolean is false? Why does it print the true statement instead?
My output is goodbye
public class Test {
public static void main (String [] args) {
if(false)
System.out.print("hello");
else System.out.print("goodbye");
}
}
Your code doesn't use the default value of boolean value.
You always print System.out.print("goodbye");, because this section is true.
To achieve this, use the following code
public class Test {
static boolean defaultValue;
public static void main(String[] args) {
System.out.println("Default value is "+defaultValue);
if(defaultValue)
System.out.println("hello");
else
System.out.println("goodbye");
}
}
What sweeper told you in a comment is correct. You seem to be under a wrong impression regarding the syntax I think. Take the following piece of code you gave as an example.
if (false) {
System.out.print("hello");
}
The code inside the if block will never run because the expression false will always evaluate to the boolean value false. You are asking Java to do the following: 'hey run this code if what I put inside the brackets evaluates to true but what you put inside the brackets will always evaluate to false. Thats why java will always run the code inside the else block in your example.
I hope this clears thing up a bit.
Is there a way to identify whether the following method executed completely or returned halfway through(i.e at line no 3)
static int a=0;
static void test(){
if(a>10){
return;
}
a++;
}
The method was invoked by another method.(a might have been changed by it)
I cannot change the method declaration. I am dealing with an object I created from a java file created by someone else. I am not allowed to change the original file
Your method does almost nothing and no there is no way in this example you gave to know if the method returned before complete execution but if you willing to change the function to a boolean type you can return true at complete execution and false at incomplete.
static boolean test()
{
if(a>10)
return false;
a++;
return true;
}
Run the code under debugger like jdb and set the breakpoint on the internal return statement. If the program stops at this breakpoint, this obviously means that it would return through that statement.
To make things more automated, you could try to launch the debugger and control the debugger from a Java program through Runtime. This would make the approach applicable for more use cases, while not for all.
You could use
void test(int a) {
if (a > 10) {
return;
}
a++;
System.out.println("test executed completely!");
}
Or if you want to use the information programmatically
private boolean executedCompletely;
void test(int a) {
executedCompletely = false;
if (a > 10) {
return;
}
a++;
executedCompletely = true;
}
When you use your test method, you can check whether it ran completely this way:
int initialA = a;
test();
int finalA = a;
if (finalA != initialA) {
//a has been changed, therefore the method ran completely
} else {
//a has not been changed, therefore it was not incremented, therefore the method did not run completely
}
So I recently came accros this. I was creating an if-else-statement with as it's condition a final boolean variable. Eclipse immediatly told me that the else part of the code was unreachable and therefore dead code. This was my code(compacted).
public static void main(String[] args){
final boolean state = true;
if(state == true){
System.out.println("A");
}else{
System.out.println("B");
}
}
Then I though what would happen if the code stayed the same but the variable wasn't final anymore? So I tried that and this was what happened, nothing no warnings or errors. The code:
public static void main(String[] args){
boolean state = true;
if(state == true){
System.out.println("A");
}else{
System.out.println("B");
}
}
Now I'm wondering, why is the first case detected and flagged and the second case not?
Thank you in advance.
Try this as an alternative.
public class Test061 {
public static void main(String[] args){
int a = 0;
if(1 == (a+1)){
System.out.println("A");
}else{
System.out.println("B");
}
}
}
There are still no warnings. Why?
Because the compiler does not execute your code. It only can issue a warning when it sees some "constants" or "constant expressions". Apparently when you put final the compiler then knows that this value cannot change. While if you use "real variables" or "variable expressions", it doesn't know because it doesn't execute your code (to see what the value of state or (a+1) is at this line). So in the latter case, you get no warnings. Hope this makes more sense now.
Think of it this way: the compiler does some code analysis. The first basic pattern is detected by this analysis, while the second pattern is not (probably as it's not that basic).
final means that something cannot be changed, so likely it was flagged because it can never and will never reach that else statement.
On a side note, you never have to do if(Boolean == true) you can just do if(Boolean)
The compiler does some optimization for final variable as shown below and in that case compiler knows that else part will never reached because final variable can't be changed later.
if (true) {
System.out.println("A");
} else {
System.out.println("B");
}
Read more JLS §4.12.4. final Variables
Find more possibilities for Unreachable code compiler error
First example:
When we use final keyword with a variable and assign a value to the variable, then that value can't change again. final boolean state = true; It can't have a value of "false".
Second example:
Here the variable state is not final. It has the possibility to get a value of "false".
So the different behavior is because of the final keyword.
I am new to Java and encountered a program with a 'while' loop that had the condition being an object reference/call. I traced the code thoroughly and did not see any terminating conditions for the object (it would make sense if the object in the while loop condition had a termination condition that the 'while' loop implementation caused).
NOTE: this involves 'inner'/'nested' classes, so I am not even entirely sure that that is the reason this works. How can a loop be satisfied by this manner of syntax? I will try to frame my question in the pseudocode below:
class DemoClass {
demoClassfoo() {
InnerClassdemo object2 = this.new InnerDemoClass;
// Here is where my confusion is. I always thought that the
// while loop had to terminate with a logical statement being
// satisfied: like it is calling an object?
while(object2.innerClassfoo()) {
IMPLEMENTATIONS;
}
}
class InnerDemoClass {
innerDemoClassfoo() {
IMPLEMENTATION;
}
}
public static void main(String[] args) {
DemoClass object = new DemoClass();
}
}
This works since the method innerClassfoo returns a booleanvalue, thus satisfying the while condition. By the way, the code should look like this:
class InnerDemoClass{
boolean innerDemoClassfoo(){
//implementation goes here
//make sure to ALWAYS return the value
boolean result = ...
return result;
}
}
I want my custom functions to modify / toggle a boolean variable. Let's say that I have code like
if (OK2continue) { findANDclick(new String[]{"id", "menuButton"});}
if (OK2continue) { findANDclick(new String[]{"src", ".*homeicon_calendar.*"}); }
if (OK2continue) { findANDclick(new String[]{"src", ".*cycle_templates.*"});
I want to make sure that the flow of execution stops once any of the findANDclick functions toggles the variable OK2continue
I managed my functions to modify a String variable using StringBuilder.
Can I do the same for boolean type of variable?
I can't say it is equivalent. But using MutableBoolean offers you a mutable boolean wrapper, similar to the concept of StringBuilder a mutable sequence of characters. See this JavaDoc for details.
Push this code into its own method, and use a return:
if (findANDclick(new String[]{"id", "menuButton"})) return;
if (findANDclick(new String[]{"src", ".*homeicon_calendar.*"})) return;
if (findANDclick(new String[]{"src", ".*cycle_templates.*"})) return;
Given that all your method calls are the same, you could also use a loop:
String[][] buttons = {
{"id", "menuButton"},
{"src", ".*homeicon_calendar.*"},
{"src", ".*cycle_templates.*"},
};
for (String[] button: buttons) {
if (findANDclick(button)) return;
}
You might or might not find that more readable.
You need to clarify your reference to your usage of StringBuilder.
Assuming:
You pass reference of the StringBuilder to your method. String is changed in method. If this the case, then see #Gordon Murray Dent's answer.
Your boolean flag is visible in the method but is not passed. A simple Boolean will do.
package sof_6232851;
public class SideEffectingMethod {
static Boolean flag = false;
public static void main(String[] args) {
flag = true;
System.out.format ("flag is %b\n", flag);
clickMe();
System.out.format ("flag is %b\n", flag);
}
/** this method side-effects instance variable flag */
public static void clickMe () {
flag = !flag;
}
}
[edit list item #2 to reply to OP comment]:
Note that #2 is not really recommended. You mention your desire for "readable" code. Side-effecting methods works against that goal.
public class ReturnValuesForFunAndProfit {
public static void main(String[] args) {
presentUI();
}
public static void presentUI() {
if(!clickMe("woof")) return;
if(!clickMe("meow")) return;
if(!clickMe("hello")) return;
}
public static boolean clickMe (String blah) {
// your logic here; this ex. always returns true
return true;
}
}
Well, the concept of StringBuilder is to create a mutable and extendable String wrapper (meaning the string can be extended via append and the like :) ). You'd still have to pass it as a parameter to the method in order to modify it (or use a static var - not recommended).
Since boolean can't be extended, the only similarity would be the parameter to be mutable. So you can use MutableBoolean as Gordon suggested, but you'd still have to pass it.
Another option would be to return a boolean from findANDclick(...) and use the boolean opperators like: findAndClick(...) || findAndClick(...) || findAndClick(...) which would only execute the next findAndClick(...) if the previous returned false.
Since that option is somewhat hard to maintain, especially since you might have side effects in findAndClick(...) as well as being quite static and hard to read if you have more calls in there, you might want to use a list of function objects:
class FindAndClickExecutor {
public FindAndClickExecutor(String[] params) {...}
public boolean findAndClick() {...}
}
List<FindAndClickExecutor> faces = ...; //initialize appropriately
for( FindAndClickExecutor face : faces ) {
boolean ok2continue = face.findAndClick();
if( !ok2continue ) {
break;
}
}
Edit: since there seem to be other methods as well, you might use a more general list:
interface Executor {
boolean execute();
}
class FindAndClickExecutor implements Executor {
public boolean execute() {} // findAndClick code here, set parameters using constructor
}
class FindAndSelectOptionExecutor implements Executor {
public boolean execute() {} // findAndSelectOption code here
}
List<Executor> testCase1Sequence = ...; //initialize test case 1
List<Executor> testCase2Sequence = ...; //initialize test case 2
for( Executor ex : testCase1Sequence ) {
boolean ok2continue = ex.execute();
if( !ok2continue) {
break;
}
}
This example could also be expanded on, e.g. by using a more complex return value containing the continue flag and maybe more data (use interface here as well).
Edit 2: you could also use some scripting to define and the builder pattern to generate the list of executors for each test case.