I need some help clarifying static and non-static variables. It is my understanding that static variables have the same value across all instances of a class. However, suppose I have a mix of static and non-static variables in the same class. When I reference a static variable, regardless of which instance is used, I will get the same value? Yet when I reference a non-static variable I will get the value associated with that particular class? That seems like a memory management nightmare. Is this really how it works and how is static memory handled? Are multiple copies of the variable created in each instance and then somehow sync'ed or is a reference by address created in each instance? Are there any pitfalls using a mix of static and non-static variables in the same class? TIA.
You are correct in your assertion ... sort-of. Statics aren't really shared between instances of the class because you don't need a class instance to reference one.
public class Foo {
public static String MYSTRING = "test";
}
can be accessed without an instance of Foo
String localString = Foo.MYSTRING;
I wouldn't really worry much about how the JVM chooses to store the memory references for the static variables, that is an implementation detail that is delegated to the JVM designer.
There aren't any pitfalls to having a class that defines both static and non-static (instance) variables, it happens all the time and is perfectly natural ... as long as you understand how statics work, which it seems that you do.
Taken from OCA Java SE 7 Programmer I Certification Guide: Prepare for the 1ZO-803 exam:
STATIC VARIABLES
static variables belong to a class. They are common to all instances of a class and aren’t unique to any instance of a class. static attributes exist independently of any instances of a class and may be accessed even when no instances of the class have been created. You can compare a static variable with a shared variable. A static variable is shared by all of the objects of a class.
STATIC METHODS
Static methods aren’t associated with objects and can’t use any of the instance variables of a class. You can define static methods to access or manipulate static variables
You can also use static methods to define utility methods, which are methods that usually manipulate the method parameters to compute and return an appropriate value
The non-private static variables and methods are inherited by derived classes. The static members aren’t involved in runtime polymorphism. You can’t override the static members in a derived class, but you can redefine them. Any discussion of static methods and their behavior can be quite confusing if you aren’t aware of inheritance and derived classes.
Static variables are the same throughout the program, since they are not instantiated. This is indeed the whole point of having static variables. They are not "somehow the same value", they are the same value because they are never instantiated and there's only ever one static variable of the same name from the same class during run time.
I don't know the 'memory logic' behind, but I've created an example
public class TestClass {
private static int a = 1;
private int b = 1;
public static void main(String[] args) {
TestClass firstInstance = new TestClass();
TestClass secondInstance = new TestClass();
// 'a' shouldn't be accessed like firstInstance.a, use TestClass.a instead(!)
System.out.println("firstInstance a: "+firstInstance.a+" b: "+firstInstance.b); // firstInstance a: 1 b: 1
System.out.println("secondInstance a: "+secondInstance.a+" b: "+secondInstance.b);// secondInstance a: 1 b: 1
firstInstance.a = 2;
firstInstance.b = 2;
System.out.println("firstInstance a: "+firstInstance.a+" b: "+firstInstance.b); //firstInstance a: 2 b: 2
System.out.println("secondInstance a: "+secondInstance.a+" b: "+secondInstance.b);//secondInstance a: 2 b: 1
//a is now 2 also for 'secondInstance' because it's static, secondInstance.b didn't change because b exists specifically for each instance
/*
* You can access 'a' even when no instance of TestClass exists
* think about a simple Dog class where the amount of legs is 4 for every dog, so you can make it static,
* but not every Dog has the same name, so it wouldn't be clever to make the name static
*/
}
}
Related
I'm starting to learn java, and I don't fully understand class variables and instance variables. I've seen some StackOverflow posts about accessing a variable from multiple methods, and most of the answers say to use static class variables. My question is, why can't one just use private instance variables? What are the advantages of using one over the other?
Instance variables are only accessible from instance functions (i. e. from non-static functions). Under the OOP paradigm, most of your variables will likely be instance variables.
Class variables (static) can also be accessed from class functions (static), like your main function.
Say, you have a class called Car. Every instance of this class (say, myFerrari and myBeetle) has its own variables doors, engine, gearbox et cetera. Thus, they are non-static, as are functions like drive (because you are driving an individual car, not the concept of cars).
But you might have a static variable MAX_ALLOWED_PASSENGERS which tells you how many seats a car may have before it's considered a bus instead. This is tied to the concept of cars (i. e. the class), not to any individual car. Thus, it might be static.
As a beginner, depending on your method of learning, you may not yet understand OOP and only write procedural code - which is not what Java is designed for. Thus you may encounter weirdnesses, like code examples where all functions and variables are static. This is a side effect of using Java in an unintended way and its purpose will be clear to you later on.
You can think of a static variable as a shared variable between all instances of the class. It is mostly used when you have a need of common value to be accessible across all objects of the class. Look at below example and execute it. It will clarify things. Please note that I have accessed a static variable with instance which is not the right practice but it is for demonstration purpose only.
public class A{
static int counter=1;
private int value;
public A(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
public class B{
public static void main(String[] args){
A a1 = new A(10);
A a2 = new A(12);
System.out.println(a1.value);
System.out.println(a2.value);
System.out.println(A.counter);
System.out.println(a1.counter);
System.out.println(a2.counter);
A.counter=20;
System.out.println(A.counter);
System.out.println(a1.counter);
System.out.println(a2.counter);
}
}
Notice how changing value of counter in class A impacts the result for both variables.
Ok first of all you should in most cases use instance variable.
class variables (static variable) are used when you need one instance across the whole class.
meaning if you have 2 different objects the static variable will be used for both of them, while using instance variable means that each object will hold its own vriable with its own value.
example:
public class Test{
public static int classVar=1;
public int instanceVar;
}
now this code will yield different resulkt based on the variable used:
Test o1=new Test();
o1.instanceVar=1;
Test o2=new Test();
o2.instanceVar=2;
System.out.println("class var object 1"+o1.classVar);//will result in 1 and warn that shoud be used as class level there for as Test.classVar
System.out.println("instance var object 1"+o1.classVar);//will result in 1
System.out.println("class var object 1"+o2.classVar);//will result in 1
System.out.println("instance var object 1"+o2.classVar);//will result in 2
I mean we know that Static members should only belongs to the Class,and not part of the any object created from the class . but we can also access static methods via objects right? lets say getInstaceCount() is the static member of Class CharStack.
for example I can create object here and access Static member of CharStack :
CharStack stack1 = new Charstack(10);// declaring object
int count1 = stack1.getinstanceCount();//accessing Static member with the object
so above I can also access the static member of Charstack with object stack1,so my doubt is what is the exact use of Static member if its even accessible by its object ?similarly why instance variable of a class is not accessible by Class ?
A static method doesn't make any sense with respect of a specific instance of a class.
The fact that invoking a static method on an instance is allowed shouldn't fool you: it just a design error of Java language which makes no sense.
A static method doesn't have a this reference so it makes no sense to be able to invoke it on a specific instance.
in addition a static method is not polymorphic so in any case you can't exploit this fact by calling it on an instance
Short story: static methods make sense in certain situations, but you should always call them through the class, eg CharStakc.getInstanceCount() to clarify their intended behavior, since being allowed to invoke them through instances is just a bad choice which shouldn't be allowed at all.
similarly why instance variable is not accessible by Class ?
Say you have this class:
class Foo{
public static Bar barStatic;
public Bar barInstance;
public static void main(String[] args){
Foo foo=new Foo();
Bar barInstance=Foo.barInstance;//case 1
Bar barStatic=foo.barStatic;// case 2
.....
}
}
Now in case 1 you want to access some object's instance variable. But which object? One, more or no objects of the class Foo might be in the heap. But based on what should the runtime decide which object to choose (if one exists of course).
But in case 2, even though you say foo.barStatic compiler is "smart enough" to know that foo is an instance of Foo and interprets your foo.barStatic as Foo.barStatic when you compile the code. I definitely don't like this design, it's confusing. So, you should know that everything is fine under the hood, it's just during code design it doesn't complain although as others have noted, good IDE's will warn you to follow the preferred Foo.barStatic way.
The static variable gets memory only once in class area at the time of class loading.
It makes your program memory efficient (i.e it saves memory).
The static variable can be used to refer the common property of all objects (that is not unique for each object) e.g. company name of employees,college name of students etc.
Is it bad practice to, in the class which contains the main method, declare all members of that class as static? If so, why? Is it better to, in the main method, create a new instance of the enclosing class, and run the program from the constructor so to speak?
EDIT: (clarification)
I know the concept about static and singletons and generally when to use it. But this question regards specifically the main-class of a program. #Andrew Tobilko (who apparently removed his answer..) seems to have best understood my question judging from his answer. In my case, my main-class is about 200 LOC, and it uses two other small class (< 100 LOC each), so it's a small program. The main-class contains creating a Swing GUI and some running logic, nothing which there needs to be several instances of, so I thought I might just make everything static, to be able to use everything from the static main-method. Is this motivated? A friend who codes in C# told me using a lot of static would mean death penalty in C#. Can there be some memory problems with it or something?
It's not 'better' - it depends on what you need to do.
Declaring all the members of a class as static (including methods) simply turns the class into a singleton. If that's your use-case, then yes.
Declaring an attribute as static means that there is only one copy of this attribute which is shared by all the instances of the class.
If your use-case requires creating multiple instances, and each one of these objects should have its own "private copy" of an attribute then you shouldn't declare that attribute as static.
It's recommended to read more about the topic before you continue implementing.
Static Variables:
The static key word is used to create variables that will exist independently of any instances created for the class. Only one copy of the static variable exists regardless of the number of instances of the class.
Static variables are also known as class variables. Local variables cannot be declared static.
Static Methods:
The static key word is used to create methods that will exist independently of any instances created for the class.
Static methods do not use any instance variables of any object of the class they are defined in. Static methods take all the data from parameters and compute something from those parameters, with no reference to variables.
Class variables and methods can be accessed using the class name followed by a dot and the name of the variable or method.
static modifier are for class members. It should be only used when you want to get a single copy of instance through out the program.
Below is example to explain it,
public class InstanceCounter {
private static int numInstances = 0;
protected static int getCount() {
return numInstances;
}
private static void addInstance() {
numInstances++;
}
InstanceCounter() {
InstanceCounter.addInstance();
}
public static void main(String[] arguments) {
System.out.println("Starting with " +
InstanceCounter.getCount() + " instances");
for (int i = 0; i < 500; ++i){
new InstanceCounter();
}
System.out.println("Created " +
InstanceCounter.getCount() + " instances");
}
}
This would produce the following result:
Started with 0 instances
Created 500 instances
You could check this DuplicateQuestion for your reference
Static entity can give a call to or interact with static entities i.e. a static method can call only a static method or interact with a static variable. That is the property of static methods. Main class in java is mostly declared as "public static void main", which makes main a static method. Hence, the functions it calls are to be static.
Generally class used for constants will hold all final static
variables.
Utility classes holds all static methods.Eg - Math
class in Java
By Oracle's definition,
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
So this line from the same definition is a bit confusing:
Any object can change the value of a class variable...
So I tried this code and it prints 45 (although I get a warning saying "Static member accessed via instance reference"):
public class Main {
static int value = 8;
public static void main(String[] args) {
// write your code here
Main main = new Main();
main.value = 45;
System.out.println(value);
}
}
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
It's not really that "one object" can - it's just you're in code which has access to that variable, and unfortunately Java allows you to access static members (both variables and methods) as if they were instance members. This ends up with very misleading code, e.g.
Thread t = new Thread(...);
t.start();
t.sleep(1000);
The last line looks like it's asking the newly-started thread to sleep - but actually it'll make the current thread sleep.
This is basically a flaw in Java. The compiler will silently turn code like this into
Thread.sleep(1000);
or in your case
Main.value = 45;
(I believe that in an older version of Java, it would emit code that checked for nullity with the variable you were accessing the static member "through", but it doesn't even do that any more.)
Many IDEs will allow you to flag code like this with a warning or error. I would encourage you to turn on such a feature. If you see existing code like that, change it to use access the static member directly via the declaring class, so it's clear what's going on.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No, static field is accessible for modifications, as long the access modifier allows it.
main.value = 45;
The compiler will read this line at compile-time as:
Main.value = 45;
Being able to create a class with static variables and methods so that those variables and methods are shared by all instances or objects created from the class can be very useful, see When to use static methods.
When sharing a static variable in a class between multiple instances or objects created from the class, the synchronized modifier may be required in order to ensure that if the static variable is being modified by objects in more than one thread, that data integrity is maintained, see What does synchronized mean? and also see How to synchronize a static variable among threads running different instances of a class in java.
The final key word, see How final keyword works is used to determine whether a variable is immutable or not. So if you want to have a class static variable that should be immutable or a constant then you can add the final modifier to the definition. However see Java final keyword for variables which explains that the underlying value for a reference may not be immutable in the sense that functional programming means. See also what is meant by immutable as well as Why final keyword is necessary for immutable class.
You can also use modifiers such as public to determine the visibility of variables and methods in a class, see What does public static void mean in Java.
By using modifiers such as final or private the programmer is able to finely tune the visibility and modifiability of variables in class and objects instantiated from the class.
Litle example how the compiler change the object field access to a class field access.
public class A {
static int foo = 25;
static public void main(String[] arg){
B b = new B();
A a = b;
System.out.println(b.foo);
System.out.println(a.foo);
}
}
class B extends A {
static int foo = 60;
}
The output is:
60
25
It also shows that can be confiusing as it have different behaviour as for object fields.
By this definition, it is safe to deduce that a static variable belongs to the class and shouldn't be accessible for modification by any object of the class.Since all objects share it.
No. By this definition, that static variable belongs to the class and is modifiable by any instance of the class. There is no implication that when some variable is shared that it should not be modifiable. Use final if you want that.
If this was a Student class, and I had a static variable called numberOfStudents, why should one object of that class be allowed to change the value of this class variable?
To increment the value in constructor and decrement it in finalizer, for example.
A static variable has a single instance for the whole class that defines it. When an instance is created, an instance of that static variable IS NOT CREATED. There is only one, and that one is freely modifiable by any function without the need for an instance. (unless it is declared final)
I'm beginning to program in Java.
public static void main(String[]args)
A book said that I should use static in this case, but doesn't clearly say why I should or what it means.
Could you clarify this?
The concept of static has to do with whether something is part of a class or an object (instance).
In the case of the main method which is declared as static, it says that the main method is an class method -- a method that is part of a class, not part of an object. This means that another class could call a class method of another class, by referring to the ClassName.method. For example, invoking the run method of MyClass would be accomplished by:
MyClass.main(new String[]{"parameter1", "parameter2"});
On the other hand, a method or field without the static modifier means that it is part of an object (or also called "instance") and not a part of a class. It is referred to by the name of the specific object to which the method or field belongs to, rather than the class name:
MyClass c1 = new MyClass();
c1.getInfo() // "getInfo" is an instance method of the object "c1"
As each instance could have different values, the values of a method or field with the same name in different objects don't necessarily have to be the same:
MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();
c1.value // The field "value" for "c1" contains 10.
c2.value // The field "value" for "c2" contains 12.
// Because "c1" and "c2" are different instances, and
// "value" is an instance field, they can contain different
// values.
Combining the two concepts of instance and class variables. Let's say we declare a new class which contains both instance and class variables and methods:
class AnotherClass {
private int instanceVariable;
private static int classVariable = 42;
public int getInstanceVariable() {
return instanceVariable;
}
public static int getClassVariable() {
return classVariable;
}
public AnotherClass(int i) {
instanceVariable = i;
}
}
The above class has an instance variable instanceVariable, and a class variable classVariable which is declared with a static modifier. Similarly, there is a instance and class method to retrieve the values.
The constructor for the instance takes a value to assign to the instance variable as the argument. The class variable is initialized to be 42 and never changed.
Let's actually use the above class and see what happens:
AnotherClass ac1 = new AnotherClass(10);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
Notice the different ways the class and instance methods are called. The way they refer to the class by the name AnotherClass, or the instance by the name ac1. Let's go further and see the behavioral differences of the methods:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
AnotherClass.getClassVariable(); // Returns "42"
As can be seen, an instance variable is one that is held by an object (or "instance"), therefore unique to that particular instance, which in this example is the objects referred to by ac1 and ac2.
A class variable on the other hand is only unique to that entire class. To get this point across even better, let's add a new method to the AnotherClass:
public int getClassVariableFromInstance() {
return classVariable;
}
Then, run the following:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
ac1.getClassVariableFromInstance(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
ac2.getClassVariableFromInstance(); // Returns "42"
Although getClassVariableFromInstance is an instance method, as can be seen by being invoked by referring to the instances ac1 and ac2, they both return the same value, 42. This is because in both instance methods, they refer to the class method classVariable which is unique to the class, not to the instance -- there is only a single copy of classVariable for the class AnotherClass.
I hope that some what clarifies what the static modifier is used for.
The Java Tutorials from Sun has a section called Understanding Instance and Class Members, which also goes into the two types of variables and methods.
Please see a nice description on Wikipedia
For example, notice how in the Math class, you can say things like
Math.Abs(x);
without having to say
Math m = new Math();
These are static methods since you don't need an instance. Instance methods are those methods that require you to have an instance of a class.
Employee e = new Employee();
e.Terminate();
A static method is one that applies to the class a whole, not any particular member. .goExtinct() would be a method of the Duck population as a whole, not any particular duck. main is public and static because is has to always be available, and its not part of any particular class.
Usually, you have to have an object, an instance of a class, in order to call methods on it, for at least two reasons:
It depends on the object which class implements the method that is being called. For example if you have an instance of a subclass, the method in the subclass will be called instead, even though the code that calls the method is the same.
Objects usually have internal state (fields), that methods can refer to. This does not work if there is no object instance.
You create object instances by calling the class' constructor:
MyObject a = new MyObject();
Static methods are methods that are not attached to object instances. They can be called by just naming the class. As a result of this they
cannot be dynamically dispatched to subclasses (which is why you get a warning when you try to call it on object instances, that is just confusing syntax)
they cannot refer to instance state (non-static fields and other non-static methods).
Many people consider static methods a bad design pattern, and advise to not use them (except for public static void main) Look up the singleton instance pattern for an alternative.
In this particular case the main method must be static, because of the way the JVM will start loading classes and creating objects. When you start a Java program the JVM will look for the definition of the class that was passed to it and load it. So java MyClass will result in loading the definition of the MyClass class.
By definition a Java program will start executing in the main() method of the class that was passed to the JVM as the class to load initially. At this point in time no instance (object) of type MyClass has been created, so the main method has to be static to allow the start of the execution of your program.
If you want to see which classes are being loaded during the execution of a Java program you can use the -verbose:class command line option.
In any object oriented programming language like Java or C++ you create classes which at the very basic level are like BluePrints of a building. You can look at a blueprint and determine how various components are connected but you cannot actually live in it. It's the same with classes and object. Classes are blueprint and you create an instance of a class which is called an Object. For the same blueprint you can have multiple buildings , same way for one class you can have multiple objects. An Object is an instance of a class. Each method in a class can be called on an Object or an instance of a class, whereas for calling static methods you actually don't need an instance, you can directly call ClassName.method() without actually creating an instance of a class.
There will be times when you will want to define a class member that will be used independently of any object of that class. Normally a class member must be accessed only in conjunction with an object of its class. However, it is possible to create a member that can be used by itself, without reference to a specific instance. To create such a member, precede its declaration with the keyword static. When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object. You can declare both methods and variables to be static. The most common example of a static member is main( ). main( ) is declared as static
because it must be called before any objects exist.
The two types of static members are static fields and static methods:
Static field:
A field that’s declared with the static keyword, like this:
private static int ballCount:
The position of the static keyword is interchangeable with the positions of the visibility keywords (private and public, as well as protected). As a result, the following statement works, too:
static private int ballCount;
As a convention, most programmers tend to put the visibility keyword first.
The value of a static field is the same across all instances of the class. In other words, if a class has a static field named CompanyName, all objects created from the class will have the same value for CompanyName.
Static fields are created and initialized when the class is first loaded. That happens when a static member of the class is referred to or when an instance of the class is created, whichever comes first.
Static method:
A method declared with the static keyword. Like static fields, static methods are associated with the class itself, not with any particular object created from the class. As a result, you don’t have to create an object from a class before you can use static methods defined by the class.
The best-known static method is main, which is called by the Java runtime to start an application. The main method must be static, which means that applications run in a static context by default.
One of the basic rules of working with static methods is that you can’t access a nonstatic method or field from a static method because the static method doesn’t have an instance of the class to use to reference instance methods or fields.