Methods vs Method assigned to variables in Java - java

I'm sort of confused, I guess this question is just a matter of preference, I just want to understand the difference of the following code.
if (IsRegistered() == true) ...
public boolean IsRegistered()
{
private boolean status = false;
// blah blah code here
return status;
}
vs
isRegistered = IsRegistered();
if (isRegistered)
I know both would work, I'm not being pedantic but I just want to understand so I would know my way around.

if (isRegistered() == true) ...
This is verbose since you know if it returns true it will do it, if not, it wont. So its the same as doing:
if (isRegistered()) ...
What it does, its just getting the returning boolean value from the method and checking the condition in the if statement.
Now if you wanted to check the boolean value again, you would need to re-call the method (which may have to do something complex to return that value), BUT if you assign it to a variable first and then check the condition, like this:
boolean isRegistered = isRegistered();
if (isRegistered)...
Later on the code you can just do it again without calling that method again.
if (isRegistered)... // n lines later.
hence, avoiding executing the process again.
At the end of the day, it pretty much depends on what you need to do.

When you invoke a method which has a non-void return type, the method itself resolves to a value the same way that using a variable does. You can either use that value directly or assign it to a variable and use that.

Just use:
if ( IsRegistered() )
It's the most readable code. Having a variable to "unbox" the method will not do any good; the compiler picks it up and replaces it into the control code itself in an internal optimization pass.
Also, the performance of your IsRegistered() method, when the self-optimization of machines is put aside, depends on how your "my code here" works:
source : {
private boolean status = false;
// blah blah code here
return status;
}
optimization-passed : {
return false; // When internal code does not modify "status"
preturn _status; // When internal code modifies "status"
}

Related

How do I call two functions inside an if statement that is inside a for loop in Java?

I am supposed to implement two functions that I already created (named isTargetWithinRange (what it does: given a target, this says whether a target is within range) and isTargetVisited (which checks that the target wasn't already captured)).
In this part, I am supposed to get the index of an unvisited target within the "range" (maximum distance to my target) of my current location. To do this, I am trying to create a for loop that contains an if-statement that calls my two variables.
The trouble that I am having is that I do not know how to call functions within the if-statement (that is within a for loop). I am trying to say within the if-statement that if isTargetWithinRange returns true or if isTargetVisited returns false, then the result is -1 (which in this case represents a target that is not yet captured).
if (isTargetWithinRange(i) return true || isTargetVisited(i) return false)
return -1;
}
}
I know that this question is probably incredibly confusing...but I really need help. I will try and clarify/define anything I can to get some help...
Something like this should do the job
if (isTargetWithinRange(i) || !isTargetVisited(i)) {
return -1;
}
You need to separate the method that returns true or false ( a predicate) from the action you want to take depending on the result. For example:
if(doIReturnTrue()) { // if true do something } .
The if statement will receive the result from the function, so you don't need
isTargetWithinRange(i) return true
Instead just pass the result of the method return into the if statement
if(isTargetWithinRange(i)){ // do if true etc }
To test a false result negate the return value using the logical not ! operator
if(!isTargetVisited(i)){ // do if true }
In the above when isTargetVisited returns false apply the 'logical not' to change this to true
I see that you might be new in Java. A function will return a value, in your case it is probably a boolean. Therefore you can use the following to achieve your result:
if (isTargetWithinRange(i) == true || isTargetVisited(i) == false) {
return -1;
}
Since the function will return a value, the == will check if the returned value is equal to what you want it to be.

Missing return statement error with method that has a return in for loop

I have a method that returns all the names of people in a LinkedList for a plane.
However even though there is a return statement in the method, I'm still getting told there is a missing return statement.
How can I work around this without putting another return statement in? Why isn't it considered valid? Does putting another return statement in change what is returned?
Any feedback is greatly appreciated.
public String check() {
for (Person person: passengers)
{
return person.getName();
}
}
Because if passengers is empty, the loop will never be entered.
If the loop is never entered, assuming the only return statement is in it, we have a serious problem, don't you think ? It's like if there were no return at all.
You need to add another return statement outside of the loop.
Also note that the return will automatically exit the method, so I don't think this is exactly what you wanted as per this sentence in your question :
I have a method that returns all the names of people in a LinkedList
for a plane.
Edit
As per your edit, here how you can return a list containing all names :
return passengers.
.stream()
.map(Person::getName)
.collect(Collectors.toList());
Note that you will need to change the signature of your method to
public List<String> check()
In answer to your question in the comments. You can only return a single object from a function. You could take another container and populate it with the names and return that. For example,
public LinkedList<String> check() {
LinkedList<String> names = new LinkedList<String>();
for (Person person: passengers) {
names.add( person.getName() );
}
return names;
}
What exactly are you trying to accomplish, here?
Currently, check will only ever return the name of the first passenger. Think about how your program flows and what you want it to do.
To answer your question, you need to have an 'escape' for every possible path in your code. Even if a certain block should always catch and return (not by definition, but just by how you think the code should flow), you need to handle the case such that that block doesn't catch and return. This can be done by either fixing the first block so that it really is a catch-all, or by simply returning or throwing an error if the first block doesn't catch.
i.e.
public boolean check() {
...
if (shouldAlwaysBeTrue) return false;
}
doesn't work because shouldAlwaysBeTrue is not true by definition.
public boolean check() {
...
if (shouldAlwaysBeTrue) return false;
return true;
}

JCodeModel and elseif

I'm generating Java source code with JCodeModel and want to get an "if-elseif" block like this:
if (foo){
} else if (bar) {
}
As far as I understand the according code would be something like this (where m is a JMethod):
JConditional cond = m.body()._if(JExpr.direct("foo"));
cond._elseif(JExpr.direct("bar"));
Seems to be straight forward, but the result is this:
if (foo) {
} else {
if (bar) {
}
}
You see the syntactic difference, it's not actually an "elseif". Semantically it's the same, I know, but I need it to be generated as shown before (it's part of educational software). Any way to do this?
Unfortunately you can not do this using JConditional because of its implementation. Have a look at the source of the method _elseif:
public JConditional _elseif(JExpression boolExp) {
return _else()._if(boolExp);
}
As you can see, this method just invoke _else() and then _if internally.
Actually _else() is JBlock which contains braces ({ ... }) by default. This property of JBlock can not be switched off manually because it doesn't contain such setter. braces could be switched off only through special constructor of JBlock:
public JBlock(boolean bracesRequired, boolean indentRequired) {
this.bracesRequired = bracesRequired;
this.indentRequired = indentRequired;
}
but you are not able to set you own object to _else field of JConditional object outwardly.
The only way is copy JConditional class implementation and generate your own, which will allow you such code manipulation.
UPD: Of course you can always use Reflection as workaround for manually switching flag bracesRequired of _else object to false.

Why does method require a return value after statement which is always return true?

Why does this method (test) need a return value (it is always true)?
public boolean test() { //This method must return a result of type boolean
if (true) {
return true; // always return true
}
}
and when I added return value, it warns as "Dead code". So, why don't accept first test() method
public boolean test(int i) {
if (true) {
return true;
} else { //Dead code
return false;
}
}
The method return analysis does not analyse the if condition to see if it is always true or false, as generally it wouldn't be a compile-time constant (else you wouldn't be writing an if in the first place). It simply sees that there is an if that could or could not be taken, and if it is not taken then the method does not return a value, hence the error.
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.
My completely uninformed guess is this behaviour is an artefact of how the compiler was developed; method return analysis is a vital part of compilation, to ensure you get a valid program out at the end, and so was one of the core features implemented first. Dead code analysis is a 'nice to have' and so was implemented later on, using more sophisticated algorithms (as the core compiler bits were finished by that stage)
It is a result of the depth of analysis the compiler does.
This method doesn't do anything, so yeah, it is dead code. If the method always return true, you don't need to call it, just use true instead.
In Java, if you specify a return type (boolean) you must explicitly specify the value, regardless of whether it's always the same. That does raise the question: if it's always the same, why return anything? You already know the answer in the calling code.
Why not just write:
public boolean test() {
return true;
}
As for the second part of your question, the compiler sees that the second path is never taken in the if statement and gives you a warning about it.
If you test something, it may be a value or another value. So you can't guarantee that is going to get inside the if statement.
if (someBoolean){
return true;
}
won't work cause someBoolean can be either true or false.
If your method must return something and someBoolean is false, it will not return anything.
So in this case, you can do:
if (someBoolean){
return true;
}
return false;
or simply
return someBoolean;

Purpose of "return" statement in Scala?

Is there any real reason of providing the return statement in Scala? (aside from being more "Java-friendly")
Ignoring nested functions, it is always possible to replace Scala calculations with returns with equivalent calculations without returns. This result goes back to the early days of "structured programming", and is called the structured program theorem, cleverly enough.
With nested functions, the situation changes. Scala allows you to place a "return" buried deep inside series of nested functions. When the return is executed, control jumps out of all of the nested functions, into the the innermost containing method, from which it returns (assuming the method is actually still executing, otherwise an exception is thrown). This sort of stack-unwinding could be done with exceptions, but can't be done via a mechanical restructuring of the computation (as is possible without nested functions).
The most common reason you actually would want to return from inside a nested function is to break out of an imperative for-comprehension or resource control block. (The body of an imperative for-comprehension gets translated to a nested function, even though it looks just like a statement.)
for(i<- 1 to bezillion; j <- i to bezillion+6){
if(expensiveCalculation(i, j)){
return otherExpensiveCalculation(i, j)
}
withExpensiveResource(urlForExpensiveResource){ resource =>
// do a bunch of stuff
if(done) return
//do a bunch of other stuff
if(reallyDoneThisTime) return
//final batch of stuff
}
It is provided in order to accommodate those circumstances in which it is difficult or cumbersome to arrange all control flow paths to converge at the lexical end of the method.
While it is certainly true, as Dave Griffith says, that you can eliminate any use of return, it can often be more obfuscatory to do so than to simply cut execution short with an overt return.
Be aware, too, that return returns from methods, not function (literals) that may be defined within a method.
Here is an example
This method has lots of if-else statements to control flow, because there is no return (that is what I came with, you can use your imagination to extend it). I took this from a real life example and modified it to be a dummy code (in fact it is longer than this):
Without Return:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
error()
} else {
val condition2 = doSomethingElse()
if (!condition2) {
error()
} else {
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
BadRequest("Coudln't receive receipt")
} else {
reply.hede = initializeHede()
if (reply.hede.isGood) {
success()
} else {
error()
}
}
}
}
}
With Return:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
return error()
}
val condition2 = doSomethingElse()
if (!condition2) {
return error()
}
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
return BadRequest("Coudln't receive receipt")
}
reply.hede = initializeHede()
if (reply.hede.isGood)
return success()
return error()
}
To my eyes, the second one is more readable and even manageable than the first one. The depth of indentation (with well formatted code) goes deep and deep if you don't use a return statement. And I don't like it :)
I view return as a useful when writing imperative style code, which generally means I/O code. If you're doing pure functional code, you don't need (and should not use) return. But with functional code you may need laziness to get performance equivalent to imperative code that can "escape early" using return.

Categories