What happen in method after return statement - java

public class TestReturn {
int i = 0;
public static void main(String[] args) {
TestReturn t = new TestReturn();
System.out.println(t.test());
System.out.println(t.i);
}
private int test() {
return i++;
}
}
output
0
1
My question is,
Since return value of test() is 0, i,e un-incremented, so when i print i why it is incremented. What i know is, return is the exit point of method but from this method i found that there is something happening after returning from method.
So how exactly return works?

Simple.
When you do return i++ i is initially 0. The i++ is called the post-increment and as its name says i will be incremeneted after.
Although i++ returns a value before incrementing, the method finishes this statement before heading back to main. A return won't abruptly stop this statement halfway(evaluating but not incrementing)
So you'll return 0, increment it, and then see 1 when calling System.out.println(t.i);.
Technically, the value of i is stored onto the stack, the class field is incremented, and then the copied-out values of i is returned.

It's not the return that's the problem here, it's your usage of the post-increment operator.
What happens with "return i++;" is that the value of i is returned, then the value is incremented. That's why you get 0 and 1 as the values.

The sequence of actions in executing the statement return i++; is as follows.
Evaluate the expression i++.
a. Take the value of i
b. Increment the variable.
Return the value of the expression produced by step 1.
The evaluation of the expression is completed (including the increment) within the method call ... before the call returns.
Since return value of test() is 0, i,e un-incremented, so when i print i why it is incremented.
As you can see from my explanation above, that is because i was incremented as part of the expression evaluation; step 1b.

If u wanna return 1, give return ++i;
return i++; will first return i, then increment it;
i++ can be imagined as another function like (the syntax not applicable to java tough)-
preIncrementFunction(int &i){
int j = *i;
*i = *i+1;
return j;
}
so, the value getting printed is the un-incremented value of i but the value of i has changed.

Related

Do i also need to return string outside if-else condition ,when the return type is String

The compiler keeps telling to return string.I used if-else condition and from within if-else i have returned string.The compiler problem will be solved if i put return statement at the end of the code but my problem will start .I dont understand how to solve this problem.I want to return right when its right.
Code:
public String isValidID(String id) {
if(getId().length()!=6) {//checks for 6 digit id
return "wrong";
}
else{//checks if digit contains invalid entry
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
return "wrong";
}
}
}
In reply to my comment to add return "right" at the end, you said:
but that will make the program return "right " always.Becoz after if-else condition check ,the compiler will execute rest statement and will return "right" always
Now the source of your confusion is clear: return doesn't just set the value the method will return, it also exits the method, immediately. So for instance, the return "wrong"; inside your loop will exit from the loop, and the method, immediately. This is true of all the languages I've seen that use the return keyword (whereas there are some languages, like VB/VB.Net, where you assign a value to the function's name to set the return value, but execution continues normally until you use "exit").
That's why adding return "right"; at the end is how you resolve this, because the code won't reach that point if it ever reached return "wrong"; during the program flow above it:
public String isValidID(String id) {
if(getId().length()!=6) {//checks for 6 digit id
return "wrong"; // <== Exits immediately if reached
}
else{//checks if digit contains invalid entry
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
return "wrong"; // <== Exits immediately if reached
}
}
return "right"; // <== Exits immediately if reached
// (granted, we would have exited
// below anyway :-) )
}
In any condition, you need to return "something". In your code it possible that return never executed in a certain condition. Suppose your program execution comes to if(Id.charAt(i)>'9'||Id.charAt(i)<'0') and it never gets true then what the method will return? So, You need to write the code in a manner that in condition method execution will execute a return statement which returns a String object.
Just imagine a conditon Suppose
1. getId().length()!=6 -> false
2. getId().length() is 0
3. for(int i=0;i<getId().length();i++) will never enter the loop.
Then what should the method returns when you call it.
If I can understand your logic you can just use :
public String isValidID(String id) {
return id.matches("\\d{6}") ? "correct" : "wrong";
}
You check the length if it is 6 or not then you check if all characters are digits, you can combine both of them in one instruction, just check if the input is a number with length 6 with regex.
If you want a clean solution use boolean instead of a String in this case you can use :
public boolean isValidID(String id) {
return id.matches("\\d{6}");
}
Inside your else you have another if statement, so your return its not always reached. You need another return after the for cycle.
And you are checking if something is wright or wrong you should return Boolean true or false.
public boolean isValidID(String id) { if(getId().length()!=6) {//checks for 6 digit id return false; }
else{//checks if digit contains invalid entry for(int i=0;i'9'||Id.charAt(i)<'0') return false; }
return true;// when nothing false was found.
}
}
So in your case, I would have done public boolean isValidID instead.
Here, the compiler tells you to return something in case the length of the ID is not correct and the components of the ID (so the caracters) are between 0 and 9 (for example if your ID is something like 00ggg89, then I suppose it is wrong, but if your ID is 000000, then it could be right. Here is what I would have done
public boolean isValidID(String id) {
return id.matches("[0-9]{6}");
}
Hope this helps ! :D
public String isValidID(String id) {
String result = "right";
if(getId().length()!=6) {//checks for 6 digit id
result = "wrong";
}
else{//checks if digit contains invalid entry
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
result = "wrong";
}
}
return result;
}
Edit: In case the first statement is not valid it will never get to a return statement. Thats why you have to return a String in every possible case.

Having trouble understanding return type placement( Big Java Ex 6.8)

Currently on the chapter in my book where we talk about for loops and loops. I have sometimes come across an issue where the method needs me to return something. For example consider my code
below. Basically the exercise is to get all the factors in ascending order. Now heres the issue
As you can see I need a return statement outside of the for loop. Now I guess my book didn't exactly explain this properly, or I didn't understand the concept
of return properly in java, but does our return statement always have to be in the most outer indentation if you will?
The thing is, I don't really want to return anything outside of the for loop. I just want to return i upon that condition. Why doesn't java let me do this?
Whats a good counter-action?
Ever since I started learning loops and for loops, I have been having trouble understanding this. I guess I could just system.out.println(i) instead of returning it? But then what should I return? I could also make it a void type, and then make another method to print it, I guess?
class factors{
private int num;
public factors(int num)
{
this.num = num;
}
public int getFactors()
{
for(int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
return i;
}
}
// I NEED TO PUT A RETURN STATEMENT HERE
}
}
public class test{
public static void main(String [] args)
{
factors fact = new factors(20);
System.out.println(fact.getFactors());
}
}
IT WORKS NOW ( I dont particularly like my solution)
class factors{
private int num;
public factors(int num)
{
this.num = num;
}
public void getFactors()
{
for(int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
System.out.println(i);
}
}
}
}
public class test{
public static void main(String [] args)
{
factors fact = new factors(20);
fact.getFactors();
}
}
The thing is, I don't really want to return anything outside of the for loop. I just want to return i upon that condition. Why doesn't java let me do this?
Java lets you do that. There is nothing wrong with returning inside the loop upon reaching the condition.
Java allows you to have multiple return statements, so adding another return 0; after the loop is allowed.
Java returns once it hits the first return statement, and other return statements are not executed (the method isn't executed anymore) (except for some rare edge cases with try-catch and return, but thats another story entirely).
But why is it required?
Java requires that for all possible paths there exists a return with the proper type. Even if you yourself can proof mathematically that the path Java complains about is never taken, the compiler might not be able to prove that the path is not possible at runtime. So you simply need to add an return there with a dummy value.
In your concrete example, there is a condition in which the loop gets never executed. If num <= 0, then the loop condition is never satified and the entire loop body is skipped. Without the return,the method is invalid, because you can't return nothing from an method with return type int.
So, in your example, the compiler is actually smarter then you, and prevents you from making a mistake - because it found the path you thought wouldn't occur.
new factors(-1).getFactors(); // you don't check the passed value at all ;)
From your comments, it seems that you want to return all factors. In java, you return once, and only once, from a function. This means you have to aggregate the results and return a List or array of values:
public List<Integer> getFactors(int num) {
List<Integer> factors = new ArrayList<>();
for (int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
factors.add(i);
}
}
return factors;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(new factors(20).getFactors());
// prints a comma-separated list of all factors
}
does our return statement always have to be in the most outer indentation if you will?
No.
However, all potential code paths must return something. Consider this structure:
for(int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
return i;
}
}
What happens if num is a value where the loop itself is never entered? Or what happens if the if condition is never satisfied? No return statement would ever be encountered, which is invalid.
The compiler has to guarantee that the method will return something, under any and all potential runtime conditions. So while it's perfectly valid to return from within the loop, you also must provide logic for what to return if that return statement is never reached.
Java doesn't let you do that because what happens if the if (num % i == 0) is never true?
The methods return type is int, so it has to return an int. And it's possible that the if statement could be false, not every condition is covered with a return statement.
So if you wanted to you could return something like -1, or another invalid value. Then you know that the function didn't find what it was looking for.

"return" in my method doesn't return the value when the method is called

Just finished up an assignment for my Java class; it was to create a class with a method that, when given two strings, searches for the second string in the first and counts the number of times it is found.
Here's the important bit:
for (int count = 0; count < l1; count++) {
if (one.charAt(count) == two.charAt(0)) {
for (int count2 = 0; count2 < l2; count2++) {
if (one.charAt(count) != two.charAt(count2)) {
break;
}
count++;
if (count2 == l2 - 1) {
twoCount++;
}
}
}
}
System.out.println("There are " + twoCount + " \"" + two + "\"");
return twoCount;
I included the System.out at the end because when I call the method in another program, return doesn't actually return anything, as such:
test.stringFind(one, two);
output being:
----jGRASP exec: java StringSearchRun
There are 2 "love"
----jGRASP: operation complete.
Notice how there's just that one line from my System.out? My method in the class is defined as an int, as well as the twoCount variable. So what stupid mistake did I make?
If you're method return type is int, then you have to do something with the returned value. By just calling the method and doing nothing else, nothing happens because there's either
A) No way to retrieve the returned value or
B) Nothing being done to the returned value
Why is this so? Think about it, where is the value being returned to after executing test.stringFind(one,two);? The method when called by itself returns a value that is garbage collected right away since the value's scope is only within the method call. Therefore, once the call is done, the value is discarded because it doesn't leave the scope of the method. So to fix this, either store it in another variable or use it in an expression. Here are some examples of what you can do with it in your main method,
int result = test.stringFind(one,two);
or
System.out.println(test.stringFind(one,two));

Which will be returned in a program

I was wondering what will be returned in a java program when you have multiple returns in a program.
private int numberReturner()
{
if (a) return a;
else if (b) return b;
for (int i = 1; i < board.size()-1; i++)
{
if (c) return c;
}
return d;
}
So lets say a is true, (it should return a), but wouldn't it return d because that is the final line of code in the whole program? Why is this so?
Sorry if I worded this a bit strangely...
Once any 'return' statement is encountered the method will exit execution and return that value.
That method will return d only if no other return statement is encountered before reaching that last line.
Normally, the first "return" encountered will be the one returned. But if there is a "return" statement encountered in a finally block, the "return" in the finally block will be returned.
e.g.
private int m1(){
try{
return 1;
}finally{
return 2; //this will be returned instead
}
}
If you've already "returned" you are never going to hit the subsequent returns.
The method returns a because the return statement exits from the current method, and control flow returns to where the method was invoked. Please read more about different branching keywords in Java tutorial. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
Once a return statement is executed the method ends and if it is not void the return value is returned.
I know only one exception to this rule, and you have it with the finally statement.
Take this example:
public static void main(String[] args) {
System.out.println(test());
}
private static int test() {
try {
return 1;
} finally {
return 2;
}
}
in this case test() returns 2, because the finally statement in this case is always executed before exit the method.
The current execution thread will leave a method the first time it encounters a return statement (the notable exception to this rule is with try...finally blocks, where, once a return is encountered, the finally{...} block executes before leaving the method.

Java, infinite while loop, incrementation

in the following example program in Java, I get infinite loop, and I cannot understand why:
public class Time {
public static int next(int v) {
return v++;
}
public static void main(String[] args) {
int[] z = {3, 2, 1, 0};
int i = 1;
while(i < 4) {
System.out.println(z[i]/z[i]);
i = next(i);
}
}
}
In the while-loop the method next() is invoked, and i should be incremented every time by 1: next() should return i++, and the value of i in the while loop should be incremented by one.
Why could be the reason for the infinite loop?
Thank you.
You use post incrementation.
That should work:
public static int next(int v) {
return v+1; //or ++v
}
so basically, your next function in your example, returns the same number, not incremented one.
The definition for v++ is:
Return the current value of v then add one to v
In your case, v is the method parameter which is a copy of the variable i in main, so the method just returns the same value that was passed to it. The incremented value in v is never used.
You could have used ++v. The definition of that is:
Add one to v, then return the new value
The difference here is postfix vs prefix operators.
for example:
int a = 1;
int b = a++; // sets b to to 1 THEN increments a.
// a now equals 2.
int c = ++a; // increments a THEN stores the value in c, c = 3.
calling a method which returns int++ will not do what you expect. It is not the same as having this:
while (expression) {
// code...
intValue++;
}
because in the code block above, the increment is not being passed into a seperate variable, and the full incrementation of the value will occur prior to exiting the code block, postfix or prefix form.
public static int someMethod(int n) {
return n++;
}
whereas the codeblock above will return n, then increment it later. But since your code will keep giving the same value to int n, it will keep giving the same value back since it is not incrementing your value, but rather the variable local to that method, n. Every time you pass a new value though, n is reset and will return the same thing, resulting in your infinite loop.
Is there a reason you're not using the more idiomatic and easier to read:
for(int i = 0; i < 4; i++){
System.out.println(z[i]/z[i]);
}
... or even:
for(int x : z){
System.out.println(x / x);
}
... ?
public static int next(int v) {
return ++v;
}
Don't forget arrays start with index zero in Java and division through zero throws an exception.
You should use
public static int next(int v) {
return v + 1;
}
Using v++ is wrong, as the returned value is the original value of v before incrementation.
Furthermore, using ++v or v++ in the return statement is bad style, because ++ has the side effect of modifying v, and there shouldn't be any side effects in expressions. Side effects should only be done in statements of their own to avoid confusion and undefined order of evaluation.
post increment work that sure but u ll get exception bcas of using '0' value in array . logically 0/0 is not possible its infinite so exceptio occur avoid dividing by '0' value

Categories