What's wrong with my return statement? - java

Why this code is wrong ? When I change "else if(this.power >= p)" into only "else", it's right. Can anybody give me a hint?
public boolean useBattery(double p) {
if(this.power < p) {
this.power = 0.0;
return false;
} else if(this.power >= p) {
this.power = this.power - p;
return true;
}
}

To a human reader looking at the code it seems that either the first return will be hit, or the second, but the compiler can't be sure. To the compiler it looks like:
if (condition1) {
...
return false;
} else if (condition2) {
...
return true;
}
and it needs to know, what will the method return if neither condition1 nor condition2 is true?
Whereas if you change it to a straight else,
if (condition1) {
...
return false;
} else {
...
return true;
}
then it is certain that one of the two return statements must be hit.
In fact in your method there is a chance that neither condition will be met: if one of the numbers you are comparing is NaN (the special floating point value representing "not a number"), then both of your if conditions will be false, and the method would have no return value.
There is also theoretically a possibility that some code running in another thread might alter the value of this.power between the first if check and the second, which could lead to both conditions evaluating to false. So it is not possible for the compiler to know for certain that one of the conditions will be met, even if they were logically complementary.

What happens if we don't enter any of your conditional branches? Java can't determine that you'll be able to because else if implies that there may not be another conditional branch to check.
Phrased another way, there's an implicit else block that does nothing. Since you declare a return type, having this implicit else block do nothing is an error.
An else block is always guaranteed to execute, so you will not run into the same situation with else, which is probably what you intended to use in the first place.
Think in the case of a flowchart.
If (this.power < p), then
Set power to 0
Return false
Else if (this.power >= p), then
Subtract p from power
Return true
Else (implied)
Do nothing <- this is the error

Because if you add if into the second else there might be a condition where neither of the condition will be satisfied and method will match to no return statement.
Consider this simple example:
Consider x=5; below code will match no return statement because it doesn't satisfies any condition.
if(x>5){
return true;
}
else if(x < 5){
return false;
}

You can reproduce this error with even shorter code:
public int doSomething() {
if(true) {
return 0;
}
}
This method generates compiler error missing return statement
Compiler doesn't perform intelligent static analysis of your code. It just checks statements according to specification.
Java Language Specification 8.4.7 "Method body" states that:
If a method is declared to have a return type, then a compile-time error occurs if the body of the method can complete normally.
So, compiler just checks if these statements can complete normally.
JLS 14.9.1 "The if-then Statement":
If the value is true, then the contained Statement is executed; the if-then statement completes normally if and only if execution of the Statement completes normally.
If the value is false, no further action is taken and the if-then statement completes normally.
As you can see by specification if statement can complete normally. That's why a compile-time error occurs.
On the other hand, by JLS 14.9.2 "The if-then-else Statement":
If the value is true, then the first contained Statement (the one before the else keyword) is executed; the if-then-else statement completes normally if and only if execution of that statement completes normally.
If the value is false, then the second contained Statement (the one after the else keyword) is executed; the if-then-else statement completes normally if and only if execution of that statement completes normally.
As you can see if-then-else completes if and only if one of its blocks completes normally. In your example both of them contain return statements.

Related

Calling a method in the while loop condition

I'm curious is it possible to call a method that returns a boolean value in the condition part of a while loop?
As in:
while(someMethod()!= true){
//Do stuff
}
And the method simply returns a true or false. Is this possible or not and if so is there a correct syntax or a better way?
Edit: Thanks for the quick responses. As an extension to my question is it possible to call the method multiple times for different things but require them all to be the same before exiting the loop?
For example:
while(!(someMethod(input_a) == someMethod(input_b))){
//Do stuff
}
Where both of the returned values are the returned values are equal?
Hope this will help you
public boolean functionOne(int i){
// some operation
if(i == 1) return true;
else return false;
}
public void otherFunc(){
int i = 0;
if(functionOne(i)) { // e.g: if(functionOne(i) == true)
// your code
// 0!=1 so result is fort
}
if(!functionOne(i)){ // e.g: if(functionOne(i) == false)
// your code
// 0!=1 it is false, but ! before functionOne negate so ! of false is true
}
// **for your while**
while(functionOne(i)){ // while function returns true
// code
}
// **or**
while(!functionOne(i)){ // while function returns false
// code
}
}
Yes of course!
public static boolean someMethod(){
return false;
}
public static void main(String[] args){
while(!someMethod()){
//do something
System.out.println("Hi");
}
}
Like in this code, an infinite loop will be called if the method returns false, but if the method returns true, it will just come out of the while loop. :)
Less is best:
while (!someMethod()) {
// Do stuff
}
It's never a good idea to compare to a boolean result to a boolean literal. Prefer using the result in-line, using the logical unary not operator ! as required.
Answering the now-edited version of the question, less is still best:
while (someMethod(input_a) != someMethod(input_b))
You can find the specification of the while loop in JLS Sec 14.12:
The while statement executes an Expression and a Statement repeatedly until the value of the Expression is false.
WhileStatement:
while ( Expression ) Statement
WhileStatementNoShortIf:
while ( Expression ) StatementNoShortIf
The Expression must have type boolean or Boolean, or a compile-time error occurs.
So, you can use anything which is an Expression of type boolean (or Boolean).
And if you click through the productions in the language spec:
Expression, contains
AssignmentExpression, contains
ConditionalExpression, contains
ConditionalOrExpression, contains
ConditionalAndExpression, contains
InclusiveOrExpression, contains
ExclusiveOrExpression, contains
AndExpression, contains
EqualityExpression, contains
RelationalExpression, contains
ShiftExpression, contains
AdditiveExpression, contains
MultiplicativeExpression, contains
UnaryExpression, contains
UnaryExpressionNotPlusMinus, contains
PostfixExpression, contains
Primary, contains
PrimaryNoNewArray, contains
MethodInvocation
Phew! That's pretty deeply buried! (You can read this like an inheritance hierarchy, so every MethodInvocation is a PrimaryNoNewArray, and every PrimaryNoNewArray is a Primary etc).
So, transitively, every MethodInvocation is an Expression, hence it's fine to use it as the expression in a while loop.
Addressing your edit: yes, that's fine too. If you look at the detail of the EqualityExpression:
EqualityExpression:
RelationalExpression
EqualityExpression == RelationalExpression
EqualityExpression != RelationalExpression
As already described above, you can use an EqualityExpression as the Expression in a WhileStatement. And something of the form
RelationalExpression != RelationalExpression
is an EqualityExpression by the rule shown. Since all MethodInvocations are RelationalExpressions, you can use method invocations in the while statement as you've shown:
while(someMethod(input_a) != someMethod(input_b)) {
(a != b is an easier way of writing !(a == b)).
This is the way we have done loops over java iterators. For instance:
Iterator[String] iterator = util.Arrays.asList("One", "Two", "Three").iterator();
while(iterator.hasNext()) {
println(iterator.next());
}
We have also done something similar for the JDBC ResultSet interface.

Assignment Operation Java

class string1 {
static public void main(String[] ar) {
String s1 = "test";
String s2 = new String();
if(s2=null) { // line 0
System.out.println(s1);
System.out.println(s2.length()); //Line 1
}
}
}
What i expected to happen was
a) s2 will be set to null because its an assignment operation as I am not using ==
b) And I will get a NPE at Line 1 during Runtime
and instead I got the following output as shown below.
Output is
if(s2=null)
^
required: boolean
found: String
1 error
Can someone explain why I am getting compile error ?
Java will not implicitly cast to a boolean like some languages will. You must put an expression that evaluates to a boolean inside of conditional:
if ((s2 = null) != null) { }
This condition of course makes no sense, but it's the equivalent of what you're attempting to do. It's worth noting by the way that assignments should rarely be done in a condition.
You should do like this:
if( (s2 = null) != null)
{
// do stuff
}
The reason you are getting this error because you have to explicitly put the code for boolean evaluation in conditions as Java doesn't implicitly cast it boolean.
The if condition evaluates only boolean conditions.
And the assignment operator does not give a boolean result here.
That is the reason for getting exception.
If you use if ((s2 = null) != null) instead of if(s2=null) it will work.
You should note the fact that in java there are only two boolean values : true and false unlike some other languages which use 0 as false and anything else as true .
Can someone explain why I am getting compile error ?
In an if statement the condition can either be true or false which are returned by comparison operations and by the boolean variables.
In,
if(s2=null)
the s2=null doesn't evaluate to any boolean value i.e, true or false therefore the compiler error :
required: boolean
found: String
An if-then statement is executed by first evaluating the Expression.
From, JLS - Chapter14 : Blocks and Statements
14.9.1. The if-then Statement
An if-then statement is executed by first evaluating the Expression.
If the result is of type Boolean, it is subject to unboxing
conversion (§5.1.8).
If evaluation of the Expression or the subsequent unboxing conversion
(if any) completes abruptly for some reason, the if-then statement
completes abruptly for the same reason.
Otherwise, execution continues by making a choice based on the
resulting value:
If the value is true, then the contained Statement is executed; the
if-then statement completes normally if and only if execution of the
Statement completes normally.
If the value is false, no further action is taken and the if-then statement completes normally.
Besides what everyone else said, s2 will never be null - you just assigned a new String to it! Are you sure you're not conflating string length/existence tests from other languages?

Java Servlet if statment don't need { } brackets?

I am a beginner and reading through Murach's Java Servlet and JSP... Going through the examples. Kind of stuck at this Ch11 simple shopping cart example.
I would post the whole code here but its really way to long.
I have put the full code on my dropbox link : https://dl.dropboxusercontent.com/u/36625850/Ch11-JSTL.rar
Questions:
CartServlet.java
if(quantity > 0)
cart.addItem(lineItem);
else if(quantity == 0)
cart.removeItem(lineItem);
session.setAttribute("cart", cart);
String url = "/cart.jsp";
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url);
dispatcher.forward(request, response);
This is probably a dumb question. I notice for servlet If statement you don't need { }? Why is this? I mean regular java if statements all require { } so why is the servlet any different?
cart.java
public void addItem(LineItem item)
{
String code = item.getProduct().getCode();
int quantity = item.getQuantity();
for (int i = 0; i < items.size(); i++)
{
LineItem lineItem = items.get(i);
if (lineItem.getProduct().getCode().equals(code))
{
lineItem.setQuantity(quantity);
return;
}
}
items.add(item);
}
What I can't follow is item.getProduct().getCode();. I am not really sure what would this output.
if-else clause (and all other control structure) read by block in java.
So if you put
if(x>2)
System.out.println("a"); ==> this is the next block
System.out.println("b");
if(x<2)
{ ==> this is the next block
System.out.println("a");
System.out.println("b");
}
So testing above code if x == 1 ,
in first if statement
prints --> "b"
in second if statement
prints --> "a"
"b"
Another example
if(x>2)
for(int i=0;i<100;i++) --> next block of if
for(int j=0;j<200;j++){ --> next block of first for
if(x>0)
Sysout("a"); --> next block of if
else
Sysout("b"); --> next block of else
}
In Java it's recommended always use braces.
For your second question
item.getProduct().getCode();
item is LineItem object.
Your class sure is
public class LineItem{
private Product product;
public Product getProduct(){
return product;
}
}
Product class
public class Product{
private String code;
public String getCode(){
return code;
}
}
1) Servlet is also java code and rules that are applicable to core java are applicable to Servlet too.
{} are used to combine number of statements into single block.
ex.
if(condition)
statement 1;
statement 2;
In above example statement1 will get executed only if condition evaluates to true.Statement 2 will not be part of if statement so it gets executed as normal statement.
if(condition)
{
statement 1;
statement 2;
}
Now in above example as you have enclosed statement1 and statement 2 in {} whole block will be part of if and both statement will get executed only if if(condition) evaluates to true.
2)if (lineItem.getProduct().getCode().equals(code)
In above statement lineItem.getProduct() returns product object.
So lineItem.getProduct() becomes product.getCode().equals(code).Now product.getCode() returns code object.So product.getCode().equals(code) becomes code.equals(code) And if both are equal then if evaluates true.
if you don't use any {} in if it will execute the first statement after it. If you use a {} it will execture the all statements withing {}
For example
say condition is true
if(condition)
sttmnt1; // it will execute this only
sttmnt2; // this is out of if block
and in the following case both sttmnt will be executed
if(condition){
sttmnt1;
sttmnt2;
}
So in your example
if(quantity > 0)
cart.addItem(lineItem);
else if(quantity == 0)
cart.removeItem(lineItem);
In both if and else if condition there is only one statement. So it is not necessary to use {}
to know what item.getProduct().getCode(); will return, check what class object is returning in the getProduct method of LineItem class. in the returned objec't class type check whet is the return type of getCode()
Servlet Java code is just regular Java code. Your if without brackets would work the same way in regular Java.
Your LineItem class has a method getProduct whose return value is an object that has a getCode method. What this code snippet does is compare the value of getProduct().getCode() of all entries in items with the one of the given item. If any of them match, the function breaks and returns. So in short, this method makes sure that there is only distinct values of getProduct().getCode() are in the items collection.
What you need to understand is that {} makes multiple statements appear as one block.
Sort of like statement grouping.
So when you just have one statement you don't really need the {} but when you have multiple statements the {} are useful.
I however use the brackets all the time even for one line statements because for me it looks pretty :-)
if statement is same for all.
There is no separate (Java Servlet if statement).
If there is only one statement to execute(when [if,else if,else,while,for]) satisfies , we no need to use {}(but not recommended,readability problem occurs )
ex:
if(condition){
System.out.println("hai"); // here only one statement is there to execute
}
is same as
if(condition)
System.out.println("hai");
Similarly
int i=1;
while(i++!=10){
System.out.println("hai");
}
is same as
int i=1;
while(i++!=10)
System.out.println("hai");
In Java only switch statement requires {} even though it has single case statement

Why is an error issued with an if statement in Java even though it is always true? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Compiler complains about “missing return statement” even though it is impossible to reach condition where return statement would be missing
The following method in Java compiles fine.
public String temp() {
while(true) {
if(true) {
// Do something.
}
}
}
The method has an explicit return type which is java.lang.String with no return statement though it compiles fine. The following method however fails to compile.
public String tempNew() {
if(true) {
return "someString";
}
}
A compile-time error is issued indicating "missing return statement" even though the condition specified with the if statement is always true (it has a boolean constant that is never going to be changed neither by reflection). The method must be modified something like the following for its successful compilation.
public String tempNew() {
if(true) {
return "someString";
} else {
return "someString";
}
}
or
public String tempNew() {
if(true) {
return "someString";
}
return "someString";
}
Regarding the first case with the while loop, the second case appears to be legal though it fails to compile.
Is there a reason in the second case beyond one of the compiler's features.
Because it is dead code. The dead code analysis is done in a separate pass to the method return analysis, which does some more in-depth analysis that looks inside branch conditions.
From the java tutorial:
You can implement an infinite loop using the while statement as follows:
while (true){
// your code goes here
}
so the compiler knows this is infinite, and therefore may not return - ie not necessarily needing a return statement.
The if (true) line (on it's own), on the other hand will return and therefore needs to cover all returning branches.

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.

Categories

Resources