Is it safe to write something like this in java?
if(var==2){
return true;
}
return false;
Somehow, while debugging, the compiler executes the first return, and goes to the second.
Shouldnt the method be terminated after the first return?
Yes, it's safe.
But consider writing this instead:
return (var==2);
That's perfectly safe. Alternatives are return var == 2; or return var == 2 ? true : false;
It's perfectly safe and valid Java code. And it's not possible for the return to not actually return.
If you believe it is, I suggest you do a clean and then recompile, it's possible there is a mismatch between the compiled class and your source code.
Yes it is safe! You can have as many returns as you want - the method will be terminated after the first one
Yes it's perfectly fine to do that, even though you can write it shorter than that. Perhaps it just looks like it's getting to your second return while you're visually stepping through your code, when var == 2, but it's stepping to the end of the function. You should be able to check the return value of the function after it's finished executing.
If you really wanted to be sure, you could use assert statements or even a print statement with the return value.
Related
I want to check if there are no elements in an array.
private Player[] players = new Player[maxPlayers];
public boolean activePlayer(){
for(int i = 0; i < players.length; i++){
if(players[i] != null) {
return true;
break;
}
}
return false;
}
ItelliJ marks break; red with the message unreachable statement. What does this mean and how can I fix this?
The return statement right before the break will immediately end the method, so the break will never be reached.
in simple terms, the if the first if condition is true then it will only goto "return true;" and exit... if it does not go into the If block then it will continue to loop through and end at "return false;" So yes intelliJ is right. it should never come to the "break;"
the return true; will actually do the break for you and you don't need to do it explicitly and it will return to where ever you are calling the function "activePlayers()"
If you explain why you are adding a break, we may be able to help you further
Think through the serial behavior of the program, one line at a time. If it makes it past the conditional statements, it will hit the return statement. In Java, return terminates a function, returning control to the calling function and potentially returning a value as well. The break line will never be touched!
This might help you understand the flow of control in a Java program: http://www.dickbaldwin.com/java/Java026.htm
If you add more information about what you would like the program to do/ what you expect from the break statement, we'd be happy to help!
We use return to return a value back to the calling method, so therefore once control goes inside the if block the value true is returned to the calling method hence the break will never be reached.
To put it simply, return ends the execution of the current method and returns a value back to the caller.
Well, in Java, returning a value in a function will, in order,:
1. stop executing the code inside of the function
2. return the value in the function
ItelliJ is a very snappy and "intelligent" code checker that tells you when something is wrong or buggy.
It is giving you the error, "unreachable statement" because the "break" statement never gets executed because when you return "true"... (look back at the first part of the answer)... the break statement never gets executed.
So it is therefore an "unreachable" statement that will never be executed in any case whatsoever.
So, I have this code, which is just the way I solved an exercise that was given to me, which consisted of creating a recursive function that received a number, and then gave you the sum of 1, all the numbers in between, and your number. I know I made it sound confusing, but here's an example:
If I inserted the number 5, then the returned value would have to be 15, because: 1+2+3+4+5 = 15.
public class Exercise {
public static void main(String[] args) {
int returnedValue = addNumbers(6);
System.out.print(returnedValue);
}
public static int addNumbers(int value) {
if (value == 1) return value;
return value = value + addNumbers(value-1);
}
}
Technically speaking, my code works just fine, but I still don't get why Eclipse made me write two returns, that's all I would like to know.
Is there a way I could only write "return" once?
Sure, you can write it with just one return:
public static int addNumbers(int value) {
if (value > 1) {
value += addNumbers(value - 1);
}
return value;
}
As you can see, it's done by having some variable retain the running result until you get to the end. In this case I was able to do it in-place in value, in other cases you may need to create a local variable, but the idea of storing your intermediate result somewhere until you get to the return point is a general one.
There should be two returns. Your first return says
if at 1: stop recurstion
and the second one says
continue recursion by returning my value plus computing the value less than me
You could combine them by using a ternary:
return value == 1 ? value : value + addNumbers(value - 1)
But it is not as readable.
Recursive funtions like
Fibbonacci's sequence
Fractals
Etc.
Use themselves multiple times because they contain themselves.
Feel free to correct me if I'm wrong, but I don't think there is a way to eliminate one of those returns unless you decide to put a variable outside of the method or change the method from being recursive.
In java, a method that returns a value, MUST return a value at some point, no matter what code inside of it does. The reason eclipse requires you to add the second return, is because the first return is only run if your if statement evaluates to true. If you didn't have the second return, and that if statement did not end up being true, java would not be able to leave that method, and would have no idea what to do, thus, eclipse will require you to add a return statement after that if statement.
These types of errors are called checked errors or compile time errors. This means that eclipse literally can not convert your code into a runnable file, because it does not know how; there is a syntax error, or you are missing a return, etc.
Recursive functions always have at least 2 paths, the normal ones that will recurse and the "end" paths that just return (Usually a constant).
You could, however, do something like this:
public static int addNumbers(int value) {
if (value != 1)
value = value + addNumbers(value-1);
return value;
}
But I can't say I think it's much better (Some people get as annoyed at modifying parameters as they do at multiple returns). You could, of course, create a new variable and set it to one value or the other, but then someone would get upset because you used too many lines of code and an unnecessary variable. Welcome to programming :) Your original code is probably as good as you're likely to get.
As for why "Eclipse" did that to you, it's actually Java--Java is better than most languages at making sure you didn't do something clearly wrong as soon as possible (In this case while you are typing instead of waiting for you to compile). It detected that one branch of your if returned a value and the other did not--which is clearly wrong.
Java is also very explicit forcing you to use a "return" statement where another language might let you get away with less. In Groovy You'd be tempted to eliminate the return and write something like:
def addNumbers(value){value + (value-1?0:addNumbers(value-1))}
just for fun but I certainly wouldn't call THAT more readable! Java just figures it's better to force you to be explicit in most cases.
From the wikipedia on recursion:
In mathematics and computer science, a class of objects or methods
exhibit recursive behavior when they can be defined by two properties:
A simple base case (or cases)—a terminating scenario that does not use recursion to produce an answer
A set of rules that reduce all other cases toward the base case
There are two returns because you have to handle the two cases above. In your example:
The base case is value == 1.
The case to reduce all other cases toward the base case is value + addNumbers(value-1);.
Source: https://en.wikipedia.org/wiki/Recursion#Formal_definitions
Of course there are other ways to write this, including some that do not require multiple returns, but in general multiple returns are a clear and normal way to express recursion because of the way recursion naturally falls into multiple cases.
Like the robots of Asimov, all recursive algorithms must obey three important laws:
A recursive algorithm must have a base case.
A recursive algorithm must change its state and move toward the base case.
A recursive algorithm must call itself, recursively.
Your if (value == 1) return value; return statement is the base case. That's when the recursion(calling itself) stops. When a function call happen, the compiler pushes the current state to stack then make the call. So, when that call has returned some value, it pulls the value from stack, makes calculation and return the result to upper level. That's why the other return statement is for.
Think of this like breaking up your problem:
addNumbers(3) = 3 + addNumbers(2) (this is returned by second one)
-> 2 + addNumbers(1) (this is returned by second one)
-> 1 (this is returned by base case)
I'm trying to tell a Critter program to choose an attack type randomly from four options; I thought I had my return statement bases covered, but I'm getting a "missing return statement" error from drjava:
public Attack fight(String opponent) {
int fightChoice = new Random().nextInt(4);
if(fightChoice == 0){
return Attack.ROAR;
} if(fightChoice == 1){
return Attack.POUNCE;
} if(fightChoice == 2){
return Attack.SCRATCH;
} if(fightChoice == 3){
return Attack.FORFEIT;
}
}
any idea why that may be?
Basically, the compiler is not smart enough to figure out that you've covered every possibility with the four if statements (it doesn't really know about the contract on the return value of Random.nextInt()).
You therefore need to add a dummy return after the final if. It doesn't really matter what you return there, since it's effectively dead code. However, it would be good style to return some sort of unused or clearly invalid value.
edit: On second thoughts, rather than return a dummy value, it would be better to unconditionally throw some kind of a "programmer error" exception.
You need a missing statement outside the if statement. For instance, if flightChoice == 4, none of the if conditions will hold, so you should add a return at the end of the method. This return statement has to return something of type Attack like the if branches.
You might think that your if statement's cover all possible cases but compiler just compiles the code, doesn't cover/calculate possibilities. You need to add return statement after the last if-statement.
Just think, what happens when none of your if condition is true? In that case, you would not be returning anything from that method.
You should return from every path your method can follow, else you will get missing return statement error.
You can either make your if's an if-else if block, and then add
an else at the end, and return some value from there.
Or, you can simply add a return statement at the end of your method.
You need a return statement in case no if statement is true.
The above/previous answers explain that you need a return statement at the end, in case no if is true. I would only like to add a suggestion, as a good practice (maybe not best) in this case: just return a result only at the end and assign a value for the returned result in each if (maybe add some elses to make it more efficient in this case).
I came across this code:
for (final String s : myList)
{
s.equalsIgnoreCase(test);
updateNeeded = true;
break;
}
I suspect that this is not what the programmer actually wanted to do. I believe he meant to write something like:
for (final String s : myList)
{
if(s.equalsIgnoreCase(test))
{
updateNeeded = true;
break;
}
}
However, I don't understand why there is no error in the first code snippet.
s.equalsIgnoreCase(test);
since the method .equalsIgnoreCase("anoterString") returns a boolean and it is not being assigned to anything or used within a control flow statement
It's just a method call. You don't have to use the result of a method call for anything else.
It's rarely a good idea to ignore the result of a non-void method (in particular, the return value of InputStream.read is sometimes ignored when it really shouldn't be) but the language specification makes no attempt to call this out as a problem.
It should probably meant to be as you think. You can call a method and not assigning its result, as sometimes you just don't need the result.
You are right, this is probably an error. However, Java compiler has no way of knowing that equalsIgnoreCase method is a "pure function", i.e. produces no side effects and is otherwise meaningless unless you keep its return value.
Most programming languages allow you to ignore the returned code of a method.
There are times that you would not care about the returned value and in these cases you should be allowed to.
I'm pretty certain I'm missing something really obvious here but this seems quite bizarre.
I'm developing for Android using Eclipse - and I have a method similar to which I'm debugging and it's doing something rather odd...
public boolean test() {
if (variable == value)
return true;
// more code appears here
return false;
}
Stepping through that, on the first line (the if statement) the debugger suggests that variable does indeed equal value (they've both byte variables with a value of 0) - the debugger then moves onto the 2nd line (the return true) but it then moves on to the last line (return false) - skipping everything inbetween!?
The value returned was 'false'
WTF is going on there? I'd assumed that RETURN would exit the method entirely - but the debugger (and the return value being sent back - being false) suggests that it does nothing of the sort!?
What am I missing which is staring me in the face? Are return statements as the last line of methods always executed or something?
p.s. interesting update...
The variables I'm using are assigned in code which I didn't write - I just dug-out the source and re-built/re-ran the debugger with access to that source and I found this line in it
byte variable = (byte)9;
Can you see anything wrong with that and would that perhaps explain the problem do you think!? I've emailed the author but meanwhile - erm....
Update2
OK, I've completely remade the project, cleaned and rebuilt it, uninstalled and reinstalled it into the phone and the debugger now behaves more sensibly...
The problem is clearly the use of '9' (they use 0-9 as possible values in a byte!!) - what's happened now is that although the debugger is suggesting 'variable' is "0" - it's also failing comparison to (byte)0 and thus I get a 'false' return - which is actually correct.
I'm obviously stuck until they change their code to use a short - as for accepting an answer, it's tricky as the 'rebuild everything' answers and the 'compare using (byte) or bytevalue()' answers were sort-of both right!?
If they are Byte objects allocated with new, then == will test if they are the same object in memory and return false. Try to use:
variable.byteValue() == value.byteValue()
instead.
I think your problem is that, when you use the Byte object, doing the == is not comparing the VALUES of the bytes, but is instead comparing the object in memory. This is similar to how String works.
Instead, try:
public boolean test() {
if (variable.equals(value))
return true;
// more code appears here
return false;
}
Update based on Comment
If you are comparing two bytes (particularly a variable and a value), make sure you are casting to a byte on both values (see Binary Numeric Promotion as to why). So, try:
public boolean test() {
if ((byte)variable == (byte)value)
return true;
// more code appears here
return false;
}
I don't think your code buffer in eclipse is matching what is being debugged. The only time you should see code execute past a return statement is of you are using a finally block, in which you will see the code execute in the finally block after the return statement in the debugger.
Are return statements as the last line of methods always executed or
something?
No.
Try surrounding your if block in {} and then see what happens.
Your description of your code does not match the code you pasted. I suspect that this is a symptom of the real problem: you are stepping through source code that is not the same as your compiled code. The line numbers don't match. So it looks like it's doing all kinds of wacky things. Rebuild your compiled code and debug again.
Logically, a return statement does immediately exit a method--
But before it does, other things might happen, like a finally statement after an enclosing try block.
Usually, the debugger will skip to the closing brace of a method after the return statement, rather than to the last return statement.
This makes me think there is something unusual with your method, or that the method you are seeing in the debugger is not identical to the method that is running on the device.
It shouldn't be doing it and what you know about return already is correct.
This could happen when the compiled binary is different than the source code. Try cleaning your project and rebuilding it.
You could try remove "more code appears here" and add this code line-by-line, until you find mistake. Also try restart eclipse, clean up project and redeploy application.
This behavior is normal using the Eclipse debugger. I recommend you to watch the value returned by the method itself and not the code being executed (it will be true, not false).
For example, try the following code. You will see that return true is reached, but later foo, and foo2 are not initialized (although it seems to reach return false).
public boolean test() {
if (variable == value)
return true;
int foo = 5;
int foo2 = 7;
// more code appears here
return false; }
I don't see an open bracket after your "if" statement. It should look like this:
public boolean test() {
if (variable == value) {
return true;
// more code appears here
}
return false;
}
With the additional brackets the "true" will only be associated with the IF conditions, and the false will be only if the IF conditions are not satisfied.