Access to non-static variable from static context [duplicate] - java

This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 7 years ago.
I am trying to access a boolean variable stay from my class MontyHall but cannot because it is non-static and i am trying to access it in a static context
Here is the code:
public void updateStatistics(Door door1, Door door2, Door door3)
{
this.numGames = this.numGames + 1;
oneDoor(door1, 0);
oneDoor(door2, 1);
oneDoor(door3, 2);
if (MontyHall.stay == true){
this.numStay = this.numStay + 1;
}
else{
this.numSwitch = this.numSwitch + 1;
}
}
The variable stay is located in class MontyHall. Any help would be greatly appreciated as I am very confused how to fix this
Properties of class MontyHall:
public class MontyHall {
boolean stay;
Door A = new Door("A");
Door B = new Door("B");
Door C = new Door("C");
public MontyHall(Door a, Door b, Door c){
this.A = a;
this.B = b;
this.C = c;
}}

Your code MontyHall.stay is the part where you are trying to reference it statically (by using the class name).
A non-static field will need an instantiated object in order to reference. In this case, if this method is within MontyHall, then you can use use this.stay in order to access it, instead of MontyHall.stay. If the method you've listed above is not within the MontyHall class then you will need to create a new MontyHall object like such: MontyHall montyHall = new MontyHall();
Alternatively, you may want to make your stay variable static, in which case just add a simple static keyword to the variable declaration.

am trying to access a boolean variable stay from my class MontyHall but cannot because it is non-static and i am trying to access it in a static context
Everything is clear now. Your variable stay is an instance variable which belongs to each individual object of class MontyHall. So you shouldn't contemplate making it static just to resolve the error.
To access an instance variable, you need to create an object first. (Since it belongs to a particular object and not a class):
MontyHall hall = new MontyHall();
hall.stay; //access stay from object of MontyHall
In the rule of data protection and encapsulation, you may consider making stay variable private and use getters and setters to access it.
So if you set stay as private, you will access it like this:
hall.getStay();
Last but not least, Java do not have global variables. It is a rather common misconception to perceive class variables (static variables) as global.

You can't just access variables from non-static contexts. You will have to instantiate the class first and then access bariable from that instance. So it would go something like this:
MontyHall a = MontyHall();
a.someVariable....
Note: variable should be accessible from other classes (would recommend encapsulation depending on situation).
More info in this thread: calling non-static method in static method in Java

You want to access a variable directly from the class, without creating an instance. To do so, the variable should be declared static. In that class, you should thus define it as follows:
public class MontyHall {
public static boolean stay = true;
.....
}
Now you can access it in the way you did.
Edit
Or, as the others have mentioned as well. If stay is a variable that can change within your class, you should make an instance first.
MontyHall a = new MontyHall(....);
a.stay; // This is the stay variable from MontyHall a
MontyHall b = new MontyHall(....);
b.stay; // This stay variable could have a different value

Related

Can't use class methods after initializing class [duplicate]

public class RoundCapGraph extends View {
static private int strokeWidth = 20;
public void setStrokeWidth(int strokeWidth){
this.strokeWidth = strokeWidth;
//warning : static member 'com.example.ud.RoundCapGraph.strokeWidth' accessed via instance reference
}
}
In android studio I'm trying to set strokeWidth using setStrokeWidth.
But I get warning
static member 'com.example.ud.RoundCapGraph.strokeWidth' accessed via instance reference
Question : Does 'this' keyword make new instance and access variable via new instance?
EDITED : I don't really need to set strokeWidth variable static, but I want to understand why using 'this' keyword produce particular warning
this keyword doesn't create a new instance, but this. is usually used to access instance variables.
Therefore, when the compiler sees that you try to access a static variable via this., it assumes that you might have made a mistake (i.e. that your intention was to access an instance variable), so it warns about it.
A better way to access the static variable is:
RoundCapGraph.strokeWidth = strokeWidth;
EDIT: you are setting your static variable within an instance method. This is a good indication that the compiler was right in warning you about accessing the static variable as if it was an instance variable.
You should set static variables via static methods, and set instance variables via instance methods.
When you access static member using object's instance, the instance gets replace by Class. i.e this.strokeWidth would be replace with RoundCapGraph.strokeWidth
There will be no NullPointerException due to the instance replacement.
I found a reference to this in the Java Specification: Chapter 15, Section 11: Field Access Expressions.
Example 15.11.1-2. Receiver Variable Is Irrelevant For static Field Access
The following program demonstrates that a null reference may be used to access a class (static) variable without causing an exception
public class RoundCapGraph extends View {
static private int strokeWidth = 20;
public void setStrokeWidth(int strokeWidth){
RoundCapGraph roundCapGraph = null;
roundCapGraph.strokeWidth = strokeWidth; // NullPointerException?
//warning : static member 'com.example.ud.RoundCapGraph.strokeWidth' accessed via instance reference
}
}
Correct, Static members belong to the class not to an instance.

What happens to variables/objects in inner classes of function objects?

I have a function multi2 which returns inner class Inner as an Object.
What happens to a - where is it saved and how can I access it?
public class C {
private static Object multi2(final int a) {
class Inner {
public int hashCode() {
return 2*a;
}
}
return new Inner(); // What happens to a?
// Who allocates a?
// Can I Access a?
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
}
}
What happens at the implementation level is that a copy of the value of a is saved in a synthetic instance variable declared in the compiled version of the C.Inner class.
The value of a is passed to the compiled Inner constructor via an extra parameter.
The C.Inner.hashCode method uses the value of the synthetic variable. Accessing a in the source code of Inner.hashCode is transformed into accessing the corresponding synthetic variable in the compiled code.
The variable in the outer scope must be final1. The synthetic variable must be final2 in the Inner class. This maintains the illusion that (potentially) multiple instances of the Inner class are seeing the same a variable. (They aren't, but since the variable(s) can't be changed, it is not possible for the code of the inner class to tell the difference.)
If you use javap to look at the bytecodes for the compiled example, you will see the mechanisms used to implement this in the outer and the inner classes.
1 - or effectively final from Java 8 onwards.
2 - If a could be mutated by an Inner method, then two Inner instances with the same outer class need to share a mutable variable whose lifetime is (now) longer than the stackframe for a multi2 call. That entails somehow turning a from stack variable into something that lives on the heap. It would be expensive and complicated.
You have defined the class Inner inside the function so the scope of the class will be
restricted with in the method. And your function is static so it will be live as long as the class definition is loaded. You have override the hashCode function inside the InnerClass so every time you are calling the multi2(param) you are creating the hashCode for the instance of InnerClass and returning the instance of the InnerClass.
So as for you questions, please correct me if i am wrong.
What happens to a ?
a is with in the scope of your static method, so it will be live as long as the class definition is loaded.
Who allocates a?
scope of a is restricted inside the static method and static method does not require instance to access it but as for the static method/variable allocation, i think it depends on JVM.
Can I Access a?
No you cannot access a from outside you static method, it is restricted with in your static method.
Since the "a" is a local parameter, you could use a different approach to read the "a" value:
public class C {
public static Object multi2(final int a) {
return new Inner(a);
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
}
}
class Inner{
public int valueA;
public Inner(int a)
{
valueA = a;
}
public int getA() {
return valueA;
}
public int hashCode() {
return 2*valueA;
}
}
I wanted to know what was actually happening, so I compiled your code and looked at the bytecode output.
Basically what happens is the compiler adds in a constructor to your class 'Inner'. It also adds a single parameter to that constructor which takes 'a'. If your multi2() method was NOT static then there would probably also be a parameter to take 'this' where 'this' is the instance of 'C' that multi2() is executing on. BUT since we're in static context, there is no 'this'.
The compiler adds a private final field to your class 'Inner' and sets that private field using the value passed via the constructor. The compiler also converts
new Inner()
into
new Inner(a)
Hashcode then accesses the private field containing the value for a.
If 'a' was an object instead of a primitive, then it would be the same way, but a reference would be passed through instead of an actual number value.
How do you access this variable? Well you access it with reflections, but there are many problems:
1) You don't know the name of the field made by the compiler, so you can only get the name by looking at the bytecode. Don't trust decompilers as they might change the name. You gotta look at the bytecode yourself to find out.
2) The compiler probably marks the field as final, which means even if you can get reflections to access the field for you, you won't be able to update it.
3) It is entirely up to the compiler to figure out field names. Field names could change between builds depending on the compiler and it's mood.
Inner is a so called local class. a is a parameter passed to the method multi2 and accessable within that scope. Outside of that method, you cannot access a.

If I assign a value to a variable inside a method, does it persist beyond the scope of that method?

Sorry if this is a repeat, i've tried looking for the answer to my question but could not come across the answer I'm after.
I'm very new at Java (literally started yesterday) and I am trying to understand why if I declare a variable in my class and then assign a value to it in a void method, the value associated with that variable persists beyond the method's scope. My (very) limited understanding of methods is that they have their own scope and I thought the only way to access any variable changes that had been made within a method was to return them at the end of the method. Is this not the case?
Each method in a class will inherit any attribute (variable) or any method that directly belongs to that class. Say
public class Bicycle {
public int gear;
public int speed;
// the Bicycle class has
// two methods
public void setGear(int newValue) {
gear = newValue;
}
public void speedUp(int increment) {
speed += increment;
}
}
Let's get the setGear method
public void setGear(int newValue) {
gear = newValue;
}
As you can see, I can access the 'gear' attribute because it belongs to the Bicycle class. The parameter '(int newValue)' belongs to this method exclusively, meaning I can only access this variable inside this method, like this:
public void setGear(int newValue) {
newValue = gear;
//this wouldn't make much sense logic wise, but it is
//valid code since I can use newValue only inside the setGear method
speedUp(10);
//the method 'speedUp' belongs to the bicycle class, so I can use
//it inside another method belonging to the same class
}
Alternatively, I can use the this keyword to say that I am referring class attributes, like this:
public void setGear(int gear) {
this.gear = gear;
//I am telling the method that the class attribute 'gear' will
//receive my parameter value 'gear'
//this is useful when my parameter variable name has the same
//name as my class attribute
}
Edit: forgot to give credit to the oficial oracle docs https://docs.oracle.com/javase/tutorial/java/javaOO/classes.html
The answer to this is a bit more complex.
First start to distinguish a method from a function.
A method operates on an object instantiated by calling the constructor of the class (e.g. MyClass obj = new MyClass();). From this point, your object has a state expressed by it's member variables (all variables that are not declared static in your class).
Methods (as part of the object) may change this state (unless the corresponding variables are declared final).
To be able to to so, a method inherits the scope of the class, but the variables are bound to the instance of the object, on which the method is called.
So for instance:
public class MyClass {
private int a = 0;
public void aplusplus() {a++;}
}
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
obj1.aplusplus(); // the a of obj1 is now 1
obj2.aplusplus(); // the a of obj2 is now 1
obj1.aplusplus(); // the a of obj1 is now 2
But beware! There is also a concept called hiding.
If you declare a local variable within the body of a method, it hides the class member variable. Accessing the variable by name results in accessing the local variable, instead of the member variable. This is particuallry interesting when implementing setter methods for private members, where usually the argument of the method (which is a local variable) is named exactly as the member variable. To still access the member variable, you can use this.variablename. For instance:
public class MyClass {
private int a = 0;
public void aplusplus() {a++;}
public void setA(int a) {this.a = a;}
}
You say in your question that you have declared a variable in your class. This means that any value the variable gets set to, (during method invocations), will persist across method invocations. The variable is part of this object, and as such, is referred to as an instance variable.
If you declare variables inside method definitions, they are inside the scope of the method. They are part of this.yourMethod(). These variables are said to be local to the method. You can only use these variables inside the method. The this object does not know they exist.

How to use a Get method in java

A ton of questions have been asked on how to create getter and setter methods in java. But i have yet to see one that actually tells me how to use it.
Say i have Private int i = 1; in class A and i want to access it in class B.
I would first create a get method in class A called getIntI(); which would return the value of i.
Then in class B if i wanted to create an if statement that would need the value of i how would I get int i's value. The following is my try and calling the get method which does not work.
if(getIntI == 1)
{System.out.print.ln("int i is one");}
It is probably a really stupid question but i cant find an answer for it elsewhere.
In class A:
public int getIntI(){
return i;
}
Note: Now since your variable is single character named (just I), getter method is named getIntI since the name getI makes lesser sense. But generally, getter methods are something like get+VariableName and do not involve mentioning type. For example if I had a variable called int count, my method would be named getCount instead of getIntCount. Thats the general convention.
Also, naming variables in single char formats (like x, y etc) is discouraged because it may create confusion and management difficulty in complex programs. Though in very small programs they are fine.
Moving back to topic, if you want to access method getIntI() in class B, you will either have to inherit class A or create an object of class A reference to its method.
For class B:
Creating object
A obj = new A();
if(obj.getIntI() == 1)
// Do stuff
Inheriting class A:
public class B extends A{
... // Your stuff
if(getIntI() == 1)
// Do stuff
... // Your stuff
}
Of course there are other ways but these are simpler ones.
if class B extends class A then do only this changes,
if(getIntI() == 1)
If above inheritance was not there then do this,
if(new A().getIntI() == 1)
The problem is that you need to create a object derived from class A before you can access its variables/methods using
A a = new A();
where "a" is the name of the object. Then you can access the getter method by calling a.getIntI. You can also declare the int variable as static so that you wouldn't have to instantiate any objects. An example of class A with the static variable and getter method would be:
public class A {
private static int i = 1;
public static int getIntI() {
return i;
}
}
With this, you can call the getter method with A.getIntI().
First, if you want to access one of A's non-static methods (in this case, getIntI), you need an instance of A, or you can just declare it static.
Secondly, A method call needs a parameter list, even an empty one is needed. getIntI does not need any parameters, so you should add () at the end.
Now, you can get an instance of A somewhere and call it aObj. Andd then you can use it in the if statement:
if (aObj.getIntI == 1)
And remember to add ()!
if (aObj.getIntI() == 1)
Alternatively, you can declare i in A as static. There are two main differences between a static and a non-static variable.
You don't need an instance of the declaring class to access the static variable.
Unlike non-static variables, there is only one static variable. If you have a non-static variable i, you can create lots of instances of A and each instance will have its own i
Now let's see this in action, declare i as static:
public class A {
private static int i = 1;
public static int getIntI () { return i; }
}
Note how both i and getIntI are declared static.
Then you can use in a if statement like this:
if (A.getIntI() == 1)
Note how I use the class name A to access the method, not an instance of A.

Difference between Static and final?

I'm always confused between static and final keywords in java.
How are they different ?
The static keyword can be used in 4 scenarios
static variables
static methods
static blocks of code
static nested class
Let's look at static variables and static methods first.
Static variable
It is a variable which belongs to the class and not to object (instance).
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.
A static variable can be accessed directly by the class name and doesn’t need any object.
Syntax: Class.variable
Static method
It is a method which belongs to the class and not to the object (instance).
A static method can access only static data. It can not access non-static data (instance variables) unless it has/creates an instance of the class.
A static method can call only other static methods and can not call a non-static method from it unless it has/creates an instance of the class.
A static method can be accessed directly by the class name and doesn’t need any object.
Syntax: Class.methodName()
A static method cannot refer to this or super keywords in anyway.
Static class
Java also has "static nested classes". A static nested class is just one which doesn't implicitly have a reference to an instance of the outer class.
Static nested classes can have instance methods and static methods.
There's no such thing as a top-level static class in Java.
Side note:
main method is static since it must be be accessible for an application to run before any instantiation takes place.
final keyword is used in several different contexts to define an entity which cannot later be changed.
A final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final.
A final method can't be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.
A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a blank final variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.
Note: If the variable is a reference, this means that the variable cannot be re-bound to reference another object. But the object that it references is still mutable, if it was originally mutable.
When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. Once it has been assigned, the value of the final variable cannot change.
static means it belongs to the class not an instance, this means that there is only one copy of that variable/method shared between all instances of a particular Class.
public class MyClass {
public static int myVariable = 0;
}
//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
MyClass.myVariable = 5; //This change is reflected in both instances
final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
note A note on final methods and final classes, this is a way of explicitly stating that the method or class can not be overridden / extended respectively.
Extra Reading
So on the topic of static, we were talking about the other uses it may have, it is sometimes used in static blocks. When using static variables it is sometimes necessary to set these variables up before using the class, but unfortunately you do not get a constructor. This is where the static keyword comes in.
public class MyClass {
public static List<String> cars = new ArrayList<String>();
static {
cars.add("Ferrari");
cars.add("Scoda");
}
}
public class TestClass {
public static void main(String args[]) {
System.out.println(MyClass.cars.get(0)); //This will print Ferrari
}
}
You must not get this confused with instance initializer blocks which are called before the constructor per instance.
The two really aren't similar. static fields are fields that do not belong to any particular instance of a class.
class C {
public static int n = 42;
}
Here, the static field n isn't associated with any particular instance of C but with the entire class in general (which is why C.n can be used to access it). Can you still use an instance of C to access n? Yes - but it isn't considered particularly good practice.
final on the other hand indicates that a particular variable cannot change after it is initialized.
class C {
public final int n = 42;
}
Here, n cannot be re-assigned because it is final. One other difference is that any variable can be declared final, while not every variable can be declared static.
Also, classes can be declared final which indicates that they cannot be extended:
final class C {}
class B extends C {} // error!
Similarly, methods can be declared final to indicate that they cannot be overriden by an extending class:
class C {
public final void foo() {}
}
class B extends C {
public void foo() {} // error!
}
static means there is only one copy of the variable in memory shared by all instances of the class.
The final keyword just means the value can't be changed. Without final, any object can change the value of the variable.
final -
1)When we apply "final" keyword to a variable,the value of that variable remains constant.
(or)
Once we declare a variable as final.the value of that variable cannot be changed.
2)It is useful when a variable value does not change during the life time of a program
static -
1)when we apply "static" keyword to a variable ,it means it belongs to class.
2)When we apply "static" keyword to a method,it means the method can be accessed without creating any instance of the class
Think of an object like a Speaker. If Speaker is a class, It will have different variables such as volume, treble, bass, color etc. You define all these fields while defining the Speaker class. For example, you declared the color field with a static modifier, that means you're telling the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated.
Declaring
static final String color = "Black";
will make sure that whenever this class is instantiated, the value of color field will be "Black" unless it is not changed.
public class Speaker {
static String color = "Black";
}
public class Sample {
public static void main(String args[]) {
System.out.println(Speaker.color); //will provide output as "Black"
Speaker.color = "white";
System.out.println(Speaker.color); //will provide output as "White"
}}
Note : Now once you change the color of the speaker as final this code wont execute, because final keyword makes sure that the value of the field never changes.
public class Speaker {
static final String color = "Black";
}
public class Sample {
public static void main(String args[]) {
System.out.println(Speaker.color); //should provide output as "Black"
Speaker.color = "white"; //Error because the value of color is fixed.
System.out.println(Speaker.color); //Code won't execute.
}}
You may copy/paste this code directly into your emulator and try.
Easy Difference,
Final : means that the Value of the variable is Final and it will not change anywhere. If you say that final x = 5 it means x can not be changed its value is final for everyone.
Static : means that it has only one object. lets suppose you have x = 5, in memory there is x = 5 and its present inside a class. if you create an object or instance of the class which means there a specific box that represents that class and its variables and methods. and if you create an other object or instance of that class it means there are two boxes of that same class which has different x inside them in the memory. and if you call both x in different positions and change their value then their value will be different. box 1 has x which has x =5 and box 2 has x = 6. but if you make the x static it means it can not be created again.
you can create object of class but that object will not have different x in them.
if x is static then box 1 and box 2 both will have the same x which has the value of 5. Yes i can change the value of static any where as its not final. so if i say box 1 has x and i change its value to x =5 and after that i make another box which is box2 and i change the value of box2 x to x=6. then as X is static both boxes has the same x. and both boxes will give the value of box as 6 because box2 overwrites the value of 5 to 6.
Both final and static are totally different. Final which is final can not be changed. static which will remain as one but can be changed.
"This is an example. remember static variable are always called by their class name. because they are only one for all of the objects of that class. so
Class A has x =5, i can call and change it by A.x=6; "
Static and final have some big differences:
Static variables or classes will always be available from (pretty much) anywhere. Final is just a keyword that means a variable cannot be changed. So if had:
public class Test{
public final int first = 10;
public static int second = 20;
public Test(){
second = second + 1
first = first + 1;
}
}
The program would run until it tried to change the "first" integer, which would cause an error. Outside of this class, you would only have access to the "first" variable if you had instantiated the class. This is in contrast to "second", which is available all the time.
Static is something that any object in a class can call, that inherently belongs to an object type.
A variable can be final for an entire class, and that simply means it cannot be changed anymore. It can only be set once, and trying to set it again will result in an error being thrown. It is useful for a number of reasons, perhaps you want to declare a constant, that can't be changed.
Some example code:
class someClass
{
public static int count=0;
public final String mName;
someClass(String name)
{
mname=name;
count=count+1;
}
public static void main(String args[])
{
someClass obj1=new someClass("obj1");
System.out.println("count="+count+" name="+obj1.mName);
someClass obj2=new someClass("obj2");
System.out.println("count="+count+" name="+obj2.mName);
}
}
Wikipedia contains the complete list of java keywords.
I won't try to give a complete answer here. My recommendation would be to focus on understanding what each one of them does and then it should be cleare to see that their effects are completely different and why sometimes they are used together.
static is for members of a class (attributes and methods) and it has to be understood in contrast to instance (non static) members. I'd recommend reading "Understanding Instance and Class Members" in The Java Tutorials. I can also be used in static blocks but I would not worry about it for a start.
final has different meanings according if its applied to variables, methods, classes or some other cases. Here I like Wikipedia explanations better.
Static variable values can get changed although one copy of the variable traverse through the application, whereas Final Variable values can be initialized once and cannot be changed throughout the application.

Categories

Resources