What are the rules for scope in java? - java

I'm hoping that someone can explain to me the java rules for scope in the context of these two examples:
Example 1 (illegal) -
int r = 10;
if (x >= 0){
double r = Math.sqrt(x);
}
Example 2 (legal) -
if (x >= 0){
double r = Math.sqrt(x);
}
else {
float r = 0;
}
r = 0;
As mentioned above, Example 1 is illegal while Example 2 is not. I'm hoping someone can explain why.

More context is needed. Your second example is also invalid because r is undefined for the line r = 0;.
In general though, block-scope variables cannot collide with method-scoped variables. Block-scoped variables are decalred in code blocks like while or for loops and withing if/else blocks.
In your first example int r is your method-scoped variable and double r is block-scope. They collide because they have the same name so the compiler rejects it.
In your second example double r and float r are in separate block-scopes so they don't collide. r=0 is ambigious, and by the code you've provided should fail with a "cannot find symbol" compiler error. If it's not failing you must have declared it in a different scope and not given us that information.
This is all separate from class variables. Method variables are allowed to collide with class variables. Inside a method where a class and method share a variable name, the method-scope variable is assumed unless you specify the class-scope variable with this. For example:
public class MyClass{
int r = 10;
public void printR(int x) {
double r = 20.0;
System.out.println(r); // Prints 20.0
System.out.println(this.r); // Prints 10
}
}

Related

Java questions this and arguments for constructor

I am very new with Java and now read book Shield complete reference 9th edition.
I wrote the next code:
class Area {
double Area (double x, double y){
double z;
this.z = 5; // Problem 1
return z = x*y;
};
}
class ThisIsSparta {
public static void main (String args []){
double x = 10;
double y = 5;
double z = 0;
Area result = new Area (x,y); //Problem 2
z = result.Area(x, y);
System.out.println("Test " + z);
}
}
Problem 1: I could not understand purpose of "this", I thought that it is reference to object which had call class. So in my opinion I should return to main with z = 5. Instead i'am getting an error (compiler does not pass through it).
Problem 2: In a book example constructor was called with two arguments right during declaration, but in my case compiler do not allow to do it. Yes, I could do it in the next line, but I don't understand what is wrong.
Problem 1 :
this refers to the current object. In your case, it is an object of Area.
Read more:
What is the meaning of "this" in Java?
Problem 2:
You have not defined any constructor that takes two argument.
double Area (double x, double y) is not the right signature for a constructor as it contains return type as double.
Read more on this here : Why do constructors not return values?

Scope of variable instantiated inside a method - Java

Is this code safe in Java?
public class HelloWorld {
public static void main (String args[]) {
HelloWorld h = new HelloWorld();
int y = h.getNumber(5);
int z = h.getNumber (6);
if (y == 10)
System.out.println("true");
}
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
}
My co-worker says that int number will be placed on the stack and when getNumber returns it will be popped off and could potentially be overwritten.
Is the same code potentially unsafe in C?
The HelloWorld class has no fields, and is therefore immutable. You can call your getNumber(x) function as many times as you'd like, from any thread, using the same object, and it will always give the same result for the same argument.
Maybe your co-worker is recalling horror stories in C where you can have something like static int number, which "belongs" to the method and which would get overwritten. Or maybe she's thinking about "return by reference"; even if it were, you'd be referencing a brand-new object every time because number is newly instantiated for every method call.
Your coworker is correct, sort of, but they apparently misunderstand what is going on.
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
Yes the value of 5 + 5 or 5 + 6 will be placed on the stack, but there is no danger of them being overwritten, they will properly be placed into y or z.
I suspect the confusion is from C (this type code works fine in C as well), but for pointers instead of primitives. Returning a result of malloc from a function in C can be "challenging" if you don't do it right.

Java instance variables initialization with method

I am a little bit confused about the following piece of code:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
The output here is 0 29, but I thought that this has to be a compiler error, because the variable h should have not been initialized when it comes to the method giveH(). So, does the compilation go through the lines from top to bottom? Why is this working? Why is the value of x 0 and not 29?
The default value of int is 0 (see here). Because you initialize x before h, giveH will return the default value for a int (eg 0).
If you switch the order like this
int h = 29;
int x = giveH();
the output will be
29 29
Compilation in Java doesn't need the method to be declared before it is used. The Java tutorial goes into a bit more detail on initialization.
Here's a way to think about it: the compiler will make a note to look for a method called giveH somewhere in scope, and it will only error if it leaves the scope and doesn't find it. Once it gets to the giveH declaration then the note is resolved and everyone is happy.
Also, the variable initialization for instance variables in Java is moved to the beginning of the constructor. You can think of the lines above being split into two parts, with the declaration for x and h above, and the assignment inside the constructor.
The order of declaration does matter in this case. When the variable x is initialized, h has the default value of 0, so giveH() will return that default value. After that, the variable h is given the value 29.
You can also look at the Java Language Specification sections on Field Initialization and Forward References During Field Initialization.
#Maloubobola has provided the correct answer, but since you don't seem to fully understand yet, let me try to elaborate.
When Test is created, it runs the variable initialization (x = giveH(), h= 29) once. Your misunderstanding may be that variable x is always determined by giveH(), whereas it only determines it's value when x is initialized.
That's why the order of the statements is crucial here; x is initialized before h, and therefore h is 0 when giveH() is called at x's initialization.
It's bad practice to use a method in the field initializer. You can fix this by making h final. Then it will be initialized when the class is loaded.
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
If we do not initialize the value for non static variables like x in this program JVM will provide default value zero for class level non static variables.
Once declared, all the array elements store their default values.
Elements in an array that store objects default to null.
Elements of an array that store primitive data types store:
0 for integer types (byte, short, int,long);
0.0 for decimal types (float and double);
false for boolean;
\u0000 for char data.
Actauls values will come only when we give initialize them

I cant find out what i should have in my return statement

Ok so I am new to programming(Don't laugh at me if I ask a question very easy).
A sample of my code is as follows:
public int calcGCF(int mya, int mye, int myf, int myj)
{
x = myj * myf;
y = mye* mya;
while(x != 0 && y != 0)
{
if(x % y == 0)
{
remainder = y;
}
int gcf;
gcf = y;
y = x % y;
x = gcf;
}
}
Ok. So what this code is for is to potentially solve the derivative of any problem that the user inputs. Part of solving the derivative is getting a gcf of 2 numbers and factoring it out. When I try to compile this code, it says that I am missing a return statement. I understand what that is, but when I try to say "return remainder;" it says it may not have been initialized. Can somebody please tell me what I am doing wrong in this code, and help me with what I should put in my return statement? Thank You! By the way this is with java code.
Where are the variables x, y, and remainder declared? I don't see an int remainder; statement anywhere in the code you posted. There's also no return statement in the method, so it will not compile.
Local variables (variables that you declare inside a method) must be initialized with a value before you use them anywhere where you read the value. If you do this, for example:
public int method(int a) {
int value;
if (a > 10) {
value = 99;
}
return value;
}
Then you will get the same error as you are getting, because in case a is not greater than 10, the variable value isn't assigned any value when you reach the return statement - so Java doesn't know what value to return then.
You must make sure that value is assigned a value in any possible case.
As you wish you can return the remainder. Just initialize your remainder to a value. eg: remainder=0;
I understand what that is, but when I try to say "return remainder;" it says it may not have been initialized.
So you simply need to declare, at the top of your code, something like:
remainder = 0;
I would also think about naming your variables a little more appropriately than just myj.

What does it mean for an expression to contain "at most one side effect, as its outermost operation"?

In Java Language Spex 15.7:
Code is usually clearer when each expression contains at most one side
effect, as its outermost operation
What does it mean?
It means that each expression should do one task at a time.
Consider the following two declarations:
int a = 10;
int b = 20;
Now the task is to add these two ints and increment b by 1. There are two way to do it.
int c = a + b++;
and
int c = a + b;
b++;
JLS prefers and recommends the latter one.
What this means is that:
int x = someFunction(a, b);
is clearer when someFunction(a, b) doesn't have any side-effect i.e. it doesn't change anything. Rather the only change in the above is the assignment to x.
Another example would be use of prefix/postfix incrementers.
int x = a + b;
is clearer than
int x = (a++) + (++b);
since only x is assigned to. In the second example a and b are changed in the same statement.
By limiting the side effects, you can more easily reason about the functioning of the code, and/or re-order statement invocations, including parallelising them e.g. in the below, if the methods don't have side-effects, then you can invoke the methods a(), b() and c() representing the arguments in any order, and/or in parallel.
int res = f(a(), b(), c());
Side-effect of an expression is mostly an assignment to variable during evaluation of the expression.
Notice the code:
int x = 5, y = 7;
while ((z = x-- + --y) > 0 ) {
console.out("What is 'z' now? " + z);
console.out("How many times will this be printed?");
}
Evaluation of the condition has 3 side-effects:
decrementing x
decrementing y
assignment to z
Looks twisted, isn't it?

Categories

Resources