public class Practice {
int x;
static int y;
void functionA() {
int y = 0;
System.out.println("inside non static method functionA()");
x = 10;
y = 30;
System.out.println(x);//10
System.out.println(y);//30
functionZ();
System.out.println(x);//10
System.out.println(y);//30
}
static void functionZ() {
System.out.println("inside static method functionZ()");
System.out.println("y: " + y);//prints 0, thought it was supposed to be 30?
}
public static void main(String[] args) {
Practice s = new Practice();
s.functionA();
}
}
Can someone explain why upon execution, inside functionZ(), y is printed as 0 and not 30? Before z is invoked, in functionA we've already set the value to 30. And since there is supposed to only be one copy of a static variable across all instances of an object, shouldn't it be 30?
Inside your functionA you defining a local variable y:
void functionA() {
int y = 0;
...
While you are in that function all access to y will go into this variable, so you set it to 30. This did however not impact the static variable y, which still has the value 0 and it is accessed from the static method functionZ.
To emphasize you want to access the static variable y rather than the local variable y, use the qualified identifier Practice.y.
There is a huge difference in global variable and local variable.
Global variables have the scope in the entire class.
Where as local variable have the the limited scope only within the method or the block in which it is declared.
Here you have declared static int y; which is global variable and can be accessed by functionZ().
Whereas the variable int y=0; declared in functionA() is a local variable, can only be accessed within the functionA() method itself. Meaning other methods DO NOT even know that variable even exists.
Lets say you remove static int y; and in funtionZ() method you will get an error beacuse it doesnt find any variable y
Related
Non-static final variables can be assigned a value only once.
But why this assignment can happen only either within a declaration or in the constructor?
A final variable is defined to be immutable i.e., the value assigned to it will be the one and only for that variable x. As one can read from the JLS(§4.12.4.)
A variable can be declared final. A final variable may only be
assigned to once.
Now the constructor is just like any other method, except that it is the one that gets executed first when an object (non-static) is created from the class.
Hence, final variables can be assigned through constructors.
For example take the following code:
public class Test {
public final int x;
public Test(int x) {
this.x = x;
}
}
Compiler accepts this invocation because it is guaranteed that for that particular object its class's constructor gets invoked first and doesn't invoked again (i.e. constructor gets invoked one and only one time during the entire lifetime of object.)
However following code throws error: Non-static field 'x' cannot be referenced from a static context
public class Test {
public final int x;
static {
x = 5;
}
public Test(int x) {
this.x = x;
}
}
Since x is not a static field, it cannot be initiated within a static block.
This code would also throw error: Cannot assign a value to final variable 'x'
public class Test {
public final int x;
public Test(int x) {
this.x = x;
}
public void setX(int x) {
this.x = x;
}
}
That is because it is not guaranteed for this object, that the method setX would run first and only once. The programmer could call this method multiple times. Hence, the compiler throws an error.
So there is no way to make a variable "initializable" only once (e.g.,
a setter would block if variable was already assigned before) solely
with java syntax? I thought final might work this way but now I see
it's not.
For your question, you could simply make a variable private and add the condition to the setter method to add value only if variable is null.
For example:
public class Test {
private Integer x;
public Test() {
}
public Test(int x) {
this.x = x;
}
public void setX(int x) {
if (null == this.x) this.x = x;
}
public static void main(String[] args) {
Test y = new Test(5);
System.out.println(y.x);
y.setX(20);
System.out.println(y.x);
}
}
This is not thread safe by the way. I just added a simple example.
What does the keyword final mean in Java?
When used in a class declaration, it means that the class cannot be extended.
When used in a method, it means that the method cannot be overridden.
When used in a method parameter, it means the value of such parameter cannot be changed inside the method. (local constant)
When used in a class field ("variable), it means that it is a global constant.
Values for constants must be resolved at compile time. And, as the word implies, constants fields cannot change value. Therefore, the compiler does not allow the value to be set from a setter (mutator) method.
Contrary to what many believe, for a field to be constant, it does not have to be declared static and final. That said, since the value of a constant cannot be changed, each class instance will share the same value. Therefore, explicitly making them static reenforces this notion.
There is a fifth use of the keyword final and this is when used when local variables are declared. This is a more lengthy explanation.
What happens when you compile code?
I updated my answer because I think part of the problem is that some developers don't quite understand what happens when the code is compiled. As I mentioned before, constant values are resolved at COMPILE TIME. To understand this concept, consider the following example:
public class MyClass {
private final double PI = 3.14159;
// rest of class left out intentionally
}
If I compile this class on my laptop and then I deploy the code to some remote server, how does the server know that the global constant field PI has an assigned value of 3.14159? This is because when I compile this code, this value gets packaged with the byte code. The class constructor doesn't come into play at all in this case. HOWEVER, if the constant field is initialized to its DEFAULT value, then permanent (constant) value may be assigned via the constructor
public class MyClass {
private final double PI; // default value of 0.0
public MyClass(double value) {
PI = value;
}
// rest of code omitted intentionally
}
Here's where declaring a constant as static makes a difference. If a constant is also static, you can't do the above because calling a constructor implies that you can have multiple instances of MyClass and each instance could set a different value. This is clearly a violation of what a static member is. So, if you MUST declare a field as both static and final, understand that you cannot assign a value using this second approach. Only the first one I showed is allowed.
Final Stop's a Variable’s Reassignment
a short simple answer:
Use the keyword final when you want the compiler to prevent a variable from being re-assigned to a different object.
Whether the variable is a static variable, member variable, local variable, or argument/parameter variable, the effect is entirely the same.
Hope this helps friend =)
#StaySafe
I am currently trying to create a multithread that will display all the even numbers, then odd numbers, from 0 - 30. My question is, how can I use my x variable to set what i is equal to?
import java.util.*;
class multiThread implements Runnable {
multiThread(int a) {
int x = a;
}
public void run() {
try {
for(int i=x; i<=30;i=i+2) {
System.out.println(i);
}
}catch(Exception e){
}
}
}
Use int x variable as a class variable like this,
private int x;
This int x local variable can't access on for loop block
The variable 'int x' is define in function 'multiThread(int a)',
So you can only use it belong its own scope.
I think you'd better define the variable 'int x' in class scope.
If you run the below code snippet, you will get this output for the final variable X and Y.
X = 1 Y = 2 X = 4 Y = 5
Its obvious from the output, the final variables have been reassigned.
I am wondering, if it has violated the contract of Java Final variables. Any thoughts?
public class FinalVariablesTest {
private final int x;
private final int y;
public FinalVariablesTest() {
this.x = 1;
this.y = 2;
}
public FinalVariablesTest(int xValue, int yValue) {
this.x = xValue;
this.y = yValue;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public static void main(String...strings) {
FinalVariablesTest finalVariablesTest = new FinalVariablesTest();
System.out.println(" X = "+finalVariablesTest.getX() + " Y = "+finalVariablesTest.getY());
finalVariablesTest = new FinalVariablesTest(4,5);
System.out.println(" X = "+finalVariablesTest.getX() + " Y = "+finalVariablesTest.getY());
}
}
No, this is not a violation - There are two separate instances, and each has different final values bound to x and y.
You have changed the instance referenced by finalVariablesTest.
FinalVariablesTest class is not singleton, so you can create as many object as you want and different FinalVariablesTest Object would have different set of x and y final veriable, which you cannot change the value once created, so this is not a violation.
You have defined your variables as Final.
private final int x;
private final int y;
and you are assigning values to them in the constructor which is perfectly valid. Also you are creating two different instances of FinalVariablesTest having different values which again perfectly legal and correct.
However if you would have done something like
private static final int x;
private static final int y;
you cannot even initialize it in the constructor.Final fields don't get default values, they have to be explicitly initialized. A final variable can only be initialized once, either via an initializer or an assignment statement. If a final instance variable is not assigned a value - there will be a compiler error !
you have to initialize it while declaring
private static final int x = 0;
private static final int y = 0;
So lets say you say private static final int y; and then without creating any instance of the object you do System.out.println(FinalVariablesTest.x); that would be wrong.
Hence what you have done is perfectly valid and legal however with slight variation(making it static so variables now belong to Class rather than individual instances) you cannot do what you have experimented.
System.out.println(" X = "+finalVariablesTest.getX() + " Y = "+finalVariablesTest.getY()); prints X=1 Y=2 & X=4 Y=5 too because u creating an new object and assigning to already created object.
These are not exactly variables but rather (final) instance filed. Final instance field can be assigned exactly once, per the object they belong to. Your example creates two objects (you have two new FinalVariablesTest expressions) and for each such object the instance fields are assigned with different values.
To see what finality means, try to adding this method to your class:
public vod setX(int newValue) {
x = newValue;
}
This change will yield a compilation error due to setX trying to assign to a final field after it has already been assigned (in the constructor).
Static variables: Are the class variables and they are not created separately for each object of the class.
Instance variables: Are also the class variables but are created for each object separately.
The above definitions are just for references.
Please explain why i am getting error in this class declaration.I know it is just because i have not of initialised x.
class non_static{
public static void main(String args[])
{
int x;
System.out.println(x);
}
}
But this class declaration is totally fine.
class static_example{
static int x;
public static void main(String args[])
{
System.out.println(x);
}
}
And output of this program is 0.
Please do explain me why static member is initialized with the default value while local variables are not.
It has nothing to do with static declaration vs instance declaration. It is local declaration, which does not have a default and will cause an error when it is used uninitialized.
public class Example {
private static int stattic;
private int instancee;
public void someMethod() {
System.out.println("I am static and 0: " + stattic);
System.out.println("I am not static and 0: " + instancee);
int locall;
System.out.println("I am causing an error because I have not been initialized: " + locall);
}
}
If you want to know the background on why Java specifies it like that, it has to do wih the limits of static code analysis. Memory allocated from the stack (and this is where the local vars are) can be confirmed positively by the compiler to be initialized before use. Not so with heap-allocated storage (static vars, instance vars). This is why the JLS requires the implementations to always zero out any heap storage before exposing a pointer to it.
Local variables must always be initialized with a value. For non-local variables (i.e. instance or static variables) the default is defined as the corresponding type's null values (null, zero or false).
In java the Instance Variables (ie class variables) are initialized to their default values.
But the Local Variables (ie Method variables) CAN NOT be used without initializing...
class static_example{
static int x;
public static void main(String args[])
{
System.out.println(x);
}
}
In the above example of yours, x is declared at Class scope... So it is already initialized to its default value 0, so its NOT GIVING any error..
Say I wanted to make a class to hold a set of integers that would be accessed from multiple other classes and instances. I don't want them reverting to the value they had when the code was compiled. Does that mean they have to be static, in order to keep them from going back their original value? For example
The original stats holding class here:
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
It is called on in two places. Here:
public class exampleClass() {
private Stats stats = new Stats();
stats.numOne += 5;
//More variable changes.
}
Also here:
public class exampleClassTwo() {
private Stats stats = new Stats();
stats.numOne -= 3;
//More variable changes.
}
Will these calls reset the variables to their original class value if the variables are not static? If so, does that mean they should always be static?
No, the variables will maintain state without the static modifier
No. You would use static key word for using those values without initializating them.
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
public class exampleClass() {
int a = 0;
a += Stats.numThree;
System.out.println(a);
}
>>> 3;
No need for static attributes in your case indeed, each class instance will contain a private copy of attributes initialized at instance creation time, and records all subsequent modifications until object is deleted (in java it means no longer referenced).
Main usage for static is either to store constants or global state (e.g. a singleton instance).
Doing,
private Stats stats = new Stats();
stats.numOne += 5;
Kind of defeats the purpose of having numOne as static.
The static field numOne should be accessed in a static way i.e as follows: Stats.numOne
static variables are Class variables and are used when we want to maintain a value across instances of the class. So modifying the value of numOne across various functions will keep on changing the value of class variable numOne. Run the following code to see the effect of having a class variable in a class:
public class StaticVarDemo {
public static int staticCount =0 ;
public StaticVarDemo(){
staticCount++;
}
public static void main(String[] args) {
new StaticVarDemo();
StaticVarDemo.staticCount +=5;
System.out.println("staticCount : " + StaticVarDemo.staticCount);
new StaticVarDemo();
new StaticVarDemo();
System.out.println("staticCount : "+staticCount);
}
}
It will give the output:
staticCount : 6
staticCount : 8
Yes, when you instantiate an object, variables will be initialized to the class values when they are not static.
When a variable has the static keyword, that variable value persists over all instances: the two places you called it each create an object, both objects have the same values for their static variables (even if they are changed).
Variables without the static keyword are unique to the instance: changing it on one object doesn't affect its value on the other.
See here for more info:
What does the 'static' keyword do in a class?
It seems after some research a singleton did the job. Creating one singular instance but calling on it more then once.
See Here:
http://www.tutorialspoint.com/java/java_using_singleton.htm