Able to change Static variable value [duplicate] - java

This question already has answers here:
Difference between Static and final?
(11 answers)
Closed 4 years ago.
As mentioned in the below link Link
Static variables are initialized only once, at the start of the
execution. These variables will be initialized first, before the
initialization of any instance variables.
A single copy to be shared
by all instances of the class.
But i am able to change the value of static variable
class Test {
static int a =10;
public static void main(String args[])
{
a=20;
System.out.println("rest of the code...");
Test1 t= new Test1();
t.m();
}
}
public class Test1 {
void m ()
{
System.out.println(Test.a);
}
}

The definition means that the variable will be initialized only once in a context of the class definition. Id est, for the class Test in your example it will be initialized only once no matter the number of objects you instantiate for this class.
Take also into account that initialization is not the same as changing the value of the variable later.
To ilustrate your question in comments:
class Test {
public static long staticAtr = System.currentTimeMillis();
public long nonStaticAtr = System.currentTimeMillis();
public static void main(String[] args) {
Test t1 = new Test();
Thread.sleep(100);
Test t2 = new Test();
System.out.println(t1.staticAtr);
System.out.println(t1.nonStaticAtr);
System.out.println(t2.staticAtr);
System.out.println(t2.nonStaticAtr);
}
t1 and t2 show the same staticAtr that was initialized only once at the start of the execution, while the nonStaticAtr of t1 and t2 where initialized once per instantiation and have therefor different values.

What is meant by the quoted rule is that when you create instance A of class Test and this initialized member a with 10. If you now change the value of a in A to .e.g 12, the next created class, as well as all previous instances, will see a having a value of 12.

Related

How to build a method that increment the value of instance variable when it is called in main by an object?

I want to build a method that when it is called in main, automatically increment the value of variable.If first value is 0 when its called increment it to 1 , when I call for second time from 1 to be incremented at 2 and so on.
Notes: The method is part of a class and it called via object in main.
you can use the static variables. Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
Create a static variable whose value can be updated in a function.
let this be your class
class Student {
static int b; //initialized to zero only when class is loaded not for each object created.
public void update(){
//incrementing static variable b
b++;
}
public void showData(){
System.out.println("Value of b = "+b);
}
}
and this be your main class
public class Demo{
public static void main(String args[]){
Student s1 = new Student();
s1.update();
s1.showData();
Student s2 = new Student();
s2.update();
s1.showData();
}
}
output:
Value of b = 1
Value of b = 2
Well, you kinda left a lot up for interpretation here, assuming the "value of variable" is part of the object the code would be something like this:
public class MyClass {
public int myVariable = 0;
public MyClass() {}
public void incrementMyVariable() {
myVariable++;
}
}
How you would handle this depends on where the variable your referring to is located ie. main method, object variable, etc... Additionally, if the variable needs to be kept constant across all the objects created for the class you would need it to be static.

Storing reference to object [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 6 years ago.
I would like to store reference to variable in some class, and make operations on it inside this class. Operations should modify original variable.
In particular following code should print 1 instead of 0.
class Test {
private Long metric;
public Test(Long m) {
this.metric = m;
++this.metric;
}
}
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Long metric = 0L;
Test test = new Test(metric);
System.out.println(metric);
}
}
How to achieve this behaviour?
You can replace Long with AtomicLong which is mutable. You'll lose autoboxing features though.
The problem in your code is that Integer is an immutable class.
Every time that you change the value you are really building a new instance of Integer.
Doing the same with mutable objects will work.
For example
class Test {
private StringBuilder metric;
public Test(StringBuilder m) {
this.metric = m;
this.metric.append(" Xter");
}
}
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
StringBuilder b = new StringBuilder("Hello ");
Test test = new Test(metric);
System.out.println(b.toString());
// Will print Hello Xter
}
}
As already metioned, the primitive wrapper classes are inmutable.
Since your metric is private in Test, and you want to use its value in the calling method main, you should use the java bean guidelines and use a getter for it:
public Long getMetric(){return this.metric;}
And on main:
metric=test.getMetric();
System.out.println(metric);

Why an instance variable can be assigned and not be referenced before its declaration in Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java static class initialization
in what order are static blocks and static variables in a class executed?
When I run this code the answer is 1, I thought it would be 2.
What is the order of initialization and the value of k in each step?
public class Test {
static {k = 2;}
static int k = 1;
public static void main(String[] args) {
System.out.println(k);
}
}
Edit 1: As a follow up to "k is set to default value" then why this next code doesn't compile? Theres an error "Cannot reference a field before it's defined".
public class Test {
static {System.out.println(k);}
static int k=1;
public static void main(String[] args) {
System.out.println(k);
}
}
Edit 2: For some unknow to me reason it^ works when instead of "k" its "Test.k".
Thanks for all the answers. this will sufice :D
They are executed in the order that you write them. If the code is:
public class Test {
static int k = 1;
static {k = 2;}
public static void main(String[] args) {
System.out.println(k);
}
}
then the output becomes 2.
The order of initialization is: ..the class variable initializers and static initializers of the class..., in textual order, as though they were a single block.
And the values (for your code) are: k = 0 (default), then it's set to 2, then it's set back to 1.
You can check that it's actually set to 2 by running the following code:
private static class Test {
static {
System.out.println(Test.k);
k = 2;
System.out.println(Test.k);
}
static int k = 1;
public static void main(String[] args) {
System.out.println(k);
}
}
Short answer
When the initialization of the class starts, k will have initial value of 0.
The static block (since it precedes the assignment in the declaration) is then executed, and k will be assigned 2.
Then the initializer in the declaration is executed, and k will be assigned 1.
Long explanation
Let us use this example, since your example is a bit simple:
class TestInitOrder {
static {
System.out.println(TestInitOrder.stat1);
System.out.println(TestInitOrder.stat2);
System.out.println(TestInitOrder.str);
System.out.println(TestInitOrder.str2);
str = "something";
System.out.println(TestInitOrder.str);
System.out.println(TestInitOrder.str2);
System.out.println(TestInitOrder.lazy);
System.out.println(TestInitOrder.second);
}
private static final int stat1 = 10;
static final String str2 = "sdfff";
static String str = "crap";
private static int stat2 = 19;
static final Second second = new Second();
static final int lazy;
static {
lazy = 20;
}
static {
System.out.println(TestInitOrder.str2);
System.out.println(TestInitOrder.stat2);
System.out.println(TestInitOrder.str);
System.out.println(TestInitOrder.lazy);
System.out.println(TestInitOrder.second);
}
public static void main(String args[]) {
}
}
class Second {
public Second() {
System.out.println(TestInitOrder.second);
}
}
According to Java Language Specification, from section 4.12.5:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created
(The following lines from the specification specify the default value for all the types, basically some form of 0, such as 0, 0.0d, null, false, etc.)
So before the class is initialized (due to one of these reasons), the variables will hold an initial value.
According to the detailed initialization procedure (only the interesting steps are quoted here, and emphasis mine):
6.
[...] Then, initialize the final class variables and fields of interfaces whose values are compile-time constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28).
[...]
9.
Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
Let us look at step 6, with the 4 final class variables: stat1, str2, second, lazy.
Since 10 is constant expression, and so is "sdfff", and due to the order of execution, it is not possible to observe the initial value for str2 and stat1. In order to make an observation, the earliest you can do is in step 9.
The case of second demonstrate that when the right hand side is not a compile-time constant expression, so its initial value is visible.
The case of lazy is different, since the assignment is done in static block, and hence happen in step 9 - so it is possible to observe its initial value. (Well, the compiler checks carefully that lazy is assigned exactly once).
After the initialization of final class variables with compile-time constant expression comes the execution of static blocks and the rest of the initializers.
As you can see from the example, the static blocks and initialization happens according to textual order - demonstrated with the use of str variable - it is first printed out as null, then something, then crap.

static object references and non static object references

What is the difference between the static object references and the non-static object references ?
class example{
int r =10;
void output(){
System.out.println("The value is "+r++);
}
}
public class Test{
static example q,w,e;
public static void main(String[] args) {
q = new example();
q.output();
w = new example();
w.output();
e = new example();
e.output();
example r,t,y;
r = new example();
r.output();
t = new example();
t.output();
y = new example();
y.output();
}
}
While running this code the output of this code is same .So the question arises that what is usage of declaring a static reference variable in code and what is the difference between these static and nonstatic reference variable in java.
A static variable can be accessed from other methods of the same class, or even from other classes (if it's public). The non static variables in your code a local variables, and they are only accessible to the main method, in which they are declared.
The output is the same since you call your output method each time for a difference instance of the example class. In each of them r is initialized to 10, so r++ returns 10.
This objects are bonded with class level. It will create the example q, w, e when your class loaded. Then objects will be assigned to p, q, w when you run the method. Then you can access that objects with class reference.
example.q or example.getq() //need to create getq static method
without creating Test object.
A static variable is shared within all instances of a class and will always remain the same, a non static variable is specific to a single instance of the class.
You are creating object of one class into another so which type of object you're creating will not affect to the value of instance. The JVM always return the same type of object with its instances.

Why enum constructor can't access static field [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t enum’s constructor access static fields?
enum Test {
e1,e2;
int i=0;
static int j=5;
Test(){
System.out.println(i+" "+j);
}
}
In the above code the constructor can access the instance variable but not the static variable J.
I have read the answer relate to other author all are saying the e1 and e2 initialized before the initialization of J( static field), But according java spec all the static field
initialized when ever the class loaded to memory, that is before running of the constructor.
So before running of Test() constructor the static variable j must be initialized. I'm not able understand the restriction, can any body make me understand.I have already read the answer of the questions Why can't enum's constructor access static fields? But I am not happy with answer like :-The constructor is called before the static fields have all been initialized.
Suppose if take another example with a simple class like enum
class Test{
public static final Test t=new Test();
static int a=5;
Test(){
System.out.println(a);
}
public static void main(String[] args) {
}
}
Here according to there argument the constructor will run before the initialization of static field and it's running also as it's print 0(As JVM did the initilization). But no compilation error or no run time problem. Then why the same thing not happen with enum.
If you imagine how your enum would actually look as a class, it makes sense:
public class Test {
// Imagine you cannot move these two statements:
public static final Test e1 = new Test();
public static final Test e2 = new Test();
int i=0;
static int j=5;
private Test(){
System.out.println(i+ " " + j);
}
static int getJ() {
return j;
}
public static void main(String[] args) {
System.out.println(Test.getJ());
}
}
This prints:
0 0
0 0
5
If you can share a concrete example (rather than a theoretical one), we could suggest how to redesign the code to achieve the desired result, despite the static field limitations.
Problem is, that instances of enum are created during inicialization of static fields. And they created before initialization of your static fields.
They must be in static array values and statically accessible, so it makes sense. And as stated in anser to "Why can't enum's constructor access static fields?", its unfortunate that this happens before all user defined static field inicialization.
But if it was swapped, you could not acces enum instances in static initialization, so it would need allowing static block both before and after creation of enum values.
I don't know whether problem is because inicialization of enum values is concern of Enum class (and handled specialy by JVM (this logic is not in Enum class itself), or because you cannot put static fields before enum values.
WHY it is that way can answer only few people (eg. Josh Bloch and Neal Gafter who are stated as authors of Enum in javadoc, and maybe some unknown others)

Categories