How does the static keyword work in Java? - java

I'm reading Java tutorials from the begining and I have a question about static keyword on fields or variables. As Java said here:
Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated. A field defining the number of gears for a particular kind of bicycle could be marked as static since conceptually the same number of gears will apply to all instances.
With that, I guess that if you have an object (in this case, an instance of the class Bicycle) and a field inside of it that its static then, independently of if you are refearing to bicycle1 or bicycle2, the field that its static will have the same value. Am I wrong or I understand it well?
I mean, if I have:
Bicycle bicycle1 = new Bicycle();
Bicycle bicycle2 = new Bicycle();
and in the class Bicycle I have a static field like:
class Bicycle{
static int gears;
//Methods to set and get gears
}
And in the bicycle1 I set the value of gears to seven:
bicycle1.setGears(7);
then if I try to get the value of gears in bicycle2 I should get the same value as I set on bicycle1, right?
System.out.println(bicycle2.getGears()); //7
Well, here is where I have the doubt because as Java said in the quote that I put above:
this tells the compiler that there is exactly one copy of this variable in existence
Where is this copy stored? How the objects access to that copy? When is this copy created?

Where is this copy stored?
The copy (static variable) is stored in the Permanent Generation section, but if you use Java8 the Permanent Generation section no longer exists.
The static variables and static methods are part of the reflection data which are class-related data and not instance-related.
How do the objects access that copy?
Every instance of class (object) that you have created has a reference to the class.
When is this copy created?
It is created at runtime when the class is loaded: this is done by the classloader of the JVM when the class is first referenced.
Static variables belong to the class, and not to instances of the class.
Your intuition is right - you have only one copy regardless of how many object you create.
You can access a static variable using the name of the class, like in this example:
class Static {
static int staticField;
}
public class UseStatic {
public static void main(String[] args) {
System.out.println(Static.staticField);
}
}
The static fields are useful to create some kind of class constants.
Finally, to easily initialize a static field of a specific class you can use Static Initialization Blocks.
Sources: University course on java, java official documentation

With that, I guess that if you have an object (in this case, an
instance of the class Bicycle) and a field inside of it that its
static then, independently of if you are refearing to bicycle1 or
bicycle2, the field that its static will have the same value. Am I
wrong or I understand it well?
When you instantiate a class in Java for the first time, the JVM creates two things:
an instance. A set of non-static fields is allocated onto the heap for each of the instances that you create. These instance fields are separate from all other instances (and are used to represent their object's state).
a Class object. Every class in Java has one, and only one, Class object ... no matter how many instances of it that are created. For example, the Class object for class String is Class<String> (which is expressed as a literal as String.class). You can think of the static fields of a class as belonging to the Class object. The lifecycle of Class objects is independent of the lifecycle of class instances; Class objects exist for as long as the JVM process is running (therefore, their static fields also exist that long).
Since a class has only one Class object, and since all instances of a class share that same Class object, the static fields of a class are shared by all the class instances that exist.
In general, it is useful to think of the static keyword as meaning "independent of any instance":
a static field belongs to the Class object and not to any instance
a static method is invoked through the Class object and has no direct access to any instance
a static member class instance is not dependent on any other instance

static variables in java are stored in the class, you don't need to create a instance of it to access them.
class Bicycle{
public static int gears = 7;
//Methods to set and get gears
}
You can access the static method like this
Bicycle.gears;
So, there's just one Bicycle class declared on java, when you instantiate a class it's create one instance of bicycle with all static attributes declared.

Where is this copy stored?
Static variables are stored in some static storage (in permgen, I believe), you should not bother about it.
When is this copy created?
They are created when class is accessed first time (loaded by class loader) and never deleted (unless class is unloaded)
How the objects access to that copy?
Instance has reference to its class, and class has reverence to all its variables. How exactly C structures are laid in memory is implementation-specific detail.
Since static vars are bound to class, not instance, you do not even need to instantiate class to access them. MyClass.myStaticVar is ok.

Related

naming practice of variables in java. why class variable not package variable

i am just curious why class variable (i.e variables with static keyword) its called class variable instead of package variable. I mean if I declare a static variable in one class, i can access this variable from another class in the same package as long as it is not private.
Also, instance variables are declared inside a class and methods in that class can access instance variables, why not name them class variables... I just don't get it.
The class is basically the frame or blueprint for creating instances (objects). Static variables and methods are defined inside the frame and created when the class is loaded by the ClassLoader, so no instance needs to be created for them to exist. That's why they are class variables. They are not package variables because they belong specifically to that class. I.e. you would access them by calling MyClass.myVariable.
Instance variables only come into existence when an instance of the class i.e. an object is created by calling new(), and they are specific to that object and not specific to the class. There are as many counts of an instance variable as the number of objects of that class are created, whereas there is always just one count of the static class variable. That is why they are called instance variables, because they are specific to an instance and not to the class.
It's called class variable because it is inside a Class. Visibility doesn't matter in the naming convention.
And a non-static variable is a instance variable because it can be different among instances of a class. A Method is always the same among all the instances of that class.
Because packages consist of groups of classes working together, whereas classes are the abstractions that make up the objects in the implementation. You cannot have variables exist purely as package variables because it wouldn't give a context for which class "owns" the variable. Plus, it's just bad Object Oriented Programming.

Java clarification on instance and static variable usage from within instance and static methods?

Question in my book is asking: What restrictions are placed on instance variable and static variable access from within the definition of: 1.) An instance method? 2.) A static method?
Is my response to this concept correct?
-An instance method cannot directly access the instance variable while a static variable can be directly accessed since one copy is used throughout the class. (Each object will share this static variable as well as the static methods in the class. An instance variable is only available to each object and each object has its own copy of this instance variable.) A static method cannot access instance members of the class. A static method can however access members of the static variable.
An instance method cannot directly access the instance variable
Wrong.
while a static variable can be directly accessed since one copy is used throughout the class.
Correct.
(Each object will share this static variable as well as the static methods in the class.
Correct.
An instance variable is only available to each object and each object has its own copy of this instance variable.)
Correct.
A static method cannot access instance members of the class.
Correct.
A static method can however access members of the static variable.
Correct, if it has members, and they are accessible.
The compiler would have told you all this with 100% reliablity.
That's right, simply put:
Instance methods can access instance and static variables of the same class (if other access modifiers permit so);
Static methods can only access static variables of the same class.

Static and non static fields

just to clarify I am thinking of this right, in java a static field is a variable/field which is used by a whole class, or can be used by all objects refering to that class? And a non static field is a variable defined by an object? And a second object refering to the same class as object 1 can have a different value to object 1's static field?
A static field, or static class variable within a class is accessible before an instance of that class is created unlike instance variables. Instance variables (non-static variables) within a class are created when an instance of that class is created at run-time. Hence, non-static variables cannot be accessed until an instance of that class is created. Whereas, static class members can be accessed before that class is created or instantiated.
All instances of that class can access the same static variable. On the other hand, instance variables are individual/encapsulated to each instance of a class.
static field shared and used by all the objects and loaded when class is loaded
non static fields are separate copies for every object and loaded when an object is created
And a non static field is a variable defined by an object?
Whenever you create a new objects, each object will have its own copy of instance i.e. non static fields
And a second object refering to the same class as object 1 can have a different value to object 1's static field?
Didn't really get your question, but
If object1 and object2 are instnaces of a class, then if object1 modifies static field of class, then object2 will get the updated value
An instance attribute is one that is specific to an instance, and its value isn't shared among other instances of the same class.
On the other hand, a class (or static) attribute is one that is common to all of the class' instances, as it belongs to the class, not to an instance in particular.
So you must be careful with the static attributes, because a change in one will be reflected on all of the code that uses it, sometimes causing unexpected results. In practice, I tend to avoid static attributes, except for the cases where they have constant, immutable values.
Similar considerations apply to instance methods and static methods: an instance method can "see" both instance and static methods and attributes, whereas a static method can only refer to static methods and attributes of the class, and can't "see" the instance methods and attributes (that is unless it instantiates an object and uses it to access its instance members).
Kind of... a static object is shared between instances of a class and a non-static is specific to the instance. Same goes for methods.
As said in the reference :
If a field is declared static, there exists exactly one incarnation of
the field, no matter how many instances (possibly zero) of the class
may eventually be created. A static field, sometimes called a class
variable, is incarnated when the class is initialized (§12.4).
Refer to JLS §8.3.1.1:
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4).
By contrast, each instance of a class contains its own unique values for non-static fields. Non-static fields are incarnated when the class is instantiated:
A field that is not declared static (sometimes called a non-static field) is called an instance variable. Whenever a new instance of a class is created (§12.5), a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.

Constraint on static

static methods can call only static methods/fields from same class. Questions:
Why non static methods/fields shall not be made available to static because once static method has been called then JVM has created an object for it, which can access other parts of class if JVM allows?
Why does static methods allow objects from non static methods of other classes. Imposing restriction that they can access only static of other classes and letting a static access non static members of same class will cause any difference?
Following is the java language specification for the static methods and fields. Hope it will help you
8.3.1.1. static Fields
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4).
A field that is not declared static (sometimes called a non-static field) is called an instance variable. Whenever a new instance of a class is created (§12.5), a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
8.4.3.2. static Methods
A method that is declared static is called a class method.
It is a compile-time error to use the name of a type parameter of any surrounding declaration in the header or body of a class method.
A class method is always invoked without reference to a particular object. It is a compile-time error to attempt to reference the current object using the keyword this (§15.8.3) or the keyword super (§15.11.2).
A method that is not declared static is called an instance method, and sometimes called a non-static method.
An instance method is always invoked with respect to an object, which becomes the current object to which the keywords this and super refer during execution of the method body.
A non-static method has an implicit this object to can call on other non-static methods
A static method cannot implicitly call a non-static method as it has no object to implicitly use. There is nothing to stop you explicitly using an object to call a method.
e.g.
class Main {
public static void main(String... ignored) {
new Main().nonstatic(); // calls non-static method
}
public void nonstatic() {
nonstatic2(); // calls non-static object with implicit reference to "this"
}
public void nonstatic2() {
staticMethod(this);
}
public static void staticMethod(Main main) {
main.nonstatic3(); // static calls non-static with explicit object.
}
public void nonstatic3() {
}
static methods can call only static methods/fields from same class.
This is not true as the example shows.
Why non static methods/fields shall not be made available to static because once static method has been called then JVM has created an object for it,
The JVM could create an object automagically, but this is unlikely to be useful, esp if the object has no default constructor.
which can access other parts of class if JVM allows?
It could allow, but shouldn't IMHO as this would be more confusing than useful.
Why does static methods allow objects from non static methods of other classes.
static methods allow objects from all classes, not just other ones.
Imposing restriction that they can access only static of other classes and letting a static access non static members of same class will cause any difference?
The difference is you don't have an implicit instance of the class This is the whole point of a static method.
If you wanted an implicit instance, you would use a non-static method.
once Static method has been called than JVM has created an object for
it
This is not true. Static methods can be called without creating an object of that class defining static method (remember public static void main()).
Why does Static methods() allow objects from nonstatic methods of
other classes.
This is because other classe instance can exist irrespective of whether object of class defining static method (which access the the other class) exists.
Checkout this link for further insights.
In order to understand why static methods cannot call non static methods or access non static variables you need to understand the diffeerence between a class and an object.
Java is an object oriented language. First you define a class which holds the state(instance variables) and methods which change the state(instance variables).
But class is not an object. It is just a template for object creation, for which you use the new keyword (creating an instance of class).
Once you create an object its variables are in an inital state, and then you call methods which read or change object's state. Such variables and methods are non static in the sense that they require an object instance of a class.
However, in a class you can define a method that does not read or change the state. Method's behavior is not dependent at all on instance variables.
Such method can be declared static, which means no instance of the class is required to run the method.
You call a static method directly on a class ( without a reference to an object ):
MyClass.staticMethod();//will not read or change any state, because there is no object here
You can also call a static method on an object but will not access object's state, because its behavior does not depend nor does not change object's state. Call to obj.staticMethod(); is the same as MyClass.staticMethod();:
//Create an instance of a MyClass
MyClass obj = new MyClass();
//will not read or change any state of obj.
obj.staticMethod();
Note however that static methods are not completely stateless, they can still read or change the state of static varibables.
Note also that in Java you cannot override static methods(unlike in Delphi) - don't declare a method as static if you think subclasses will need to override it.
Therefore as rule-of-thumb declare static methods in special purpose utility classes which don't need an instance anyway, like for example java.lang.Math, otherwise
don't declare a method as static even if it doesn't read or change object's state because you might need to override it later.
Why non static methods/fields shall not be made available to static because once static method has been called then JVM has created an object for it, which can access other parts of class if JVM allows?
If static methods were allowed to access non-static methods, that would mean, an instance level method would be called without an instance of the class. Then how will you override the method?. Overriding looks at the object to call/invoke the method and if you directly call non-static (instance) methods from static methods, which object is being used to call?.
And from a design perspective -
Assume you have a class called Dog.
Every dog eats, sleeps etc . But the most important thing to remember is all these things are specific to the Dog instance. and state of each object should be accessed via instance level methods - thats the whole point of encapsulation. If you say Dog.sleep(). Which dog should sleep?

Why can other methods be "static" but a constructor cannot?

I do not understand why the main method has to be static. I understand static variables but static methods are difficult for me to grasp. Do static method exists so that one can create two methods with the same name in two different classes that won't clash with each other?
Also, I don't understand why I can't create a static constructor.
Could anyone help explain this concept?
Java has [static constructors] static initialization blocks which can be viewed as a "static constructor":
class Foo {
static String Bar;
static {
// "static constructor"
Bar = "Hello world!";
}
}
In any case, the only method in the main class which must be static is the main method. This is because it is invoked without first creating an instance of the "main class". A common technique, and the one I prefer, is to quickly get out of static context:
class Main {
int argCount;
// constructor
public Main (String[] args) {
// and back to boring ol' non-static Java
argCount = args.length;
}
void runIt () {
System.out.println("arg count: " + argCount);
}
// must be static -- no Main instance created yet
public static void main (String[] args) {
Main me = new Main(args);
me.runIt();
}
}
Also, static has nothing to do with "name clashes". A static method (or variable) is simply a method (or variable) that is not associated with a specific instance of a type. I would recommend reading through the Classes and Objects Java Tutorial and the section Understanding Instance and Class Variables.
Happy coding.
I am sharing one of the reason "why not a java constructor be static".
Simply to say, "A java constructor is always non static" because,
The purpose of the constructor is only to initialize/construct the object, and to make inheritance possible. To do these we need to use the two useful java keywords (cum non-static variables) such as this and super.
We will use 'this' to initialize the object.
We/Java will use super(ofcourse super()) to invoke super class constructor so that super object(or Object class) created first then the child object(hence the inheritance)
If the constructor is static then we cant use that two keywords(non-static variables) inside the constructor(As we know non-static stuff cant be referenced from static context)
So java constructors should not static.
Static methods belong to a class, not an object. The main method must be static because it is called first, before any other code has executed to instantiate any objects. It provides an entry point to the program. Static methods are called from outside of the container of an object. The same is true of static class variables. Only one copy exists for the entire class, as opposed to a member variable, which is created once for each object created from a class. They are used to store data for the class, such as the number of object instances have been created and not destroyed. This data belongs with the class. A good example of a static method is in the singleton pattern, where the constructor is private and can only be accessed by a static member function. A function outside the class would be unable to replicate this functionality. This method acts on class data and objects, so logically belongs to the same class. This all boils down to encapsulation. A class is responsible only for itself and knows only itself.
On the other hand, object methods are meant to operate on the data associated with a single instance of a class, an object. Constructors are the code that is used to initialize an object and set it's data to an initial state. They are executed immediately (and automatically) after the memory has been allocated to store a new object. Even if you do not explicitly define a constructor, a kind of "default constructor" is executed in order to map the object's member variables and the object's method code to the new object.
Hope this helps.
Constructor is used to create Objects.
Static is generally which is same for all objects.
So, if we have had static constructors creation of one object would affect all the other existing objects.
Static methods only reference to static variables. Therefore all the initial parameters which you are giving to create an object would change for all objects. It is no point creating similar objects for no use.
Hope this helps.... :)
Constructor is the property of an object while static has nothing to do with object. That's why there is nothing like static constructor. But we have static block to do the similar task as constructor i.e. initialization of fields etc.
On page 272 of Thinking In Java, 4th Edition, by Bruce Eckel, it says:
²The constructor is also a static method even though the static keyword is not explicit. So to be precise, a class is first loaded when any of its static members is accessed.
A little bit more context.
... the compiled code for each class exists in its own separate file. That file isn't loaded until the code is needed. In general you can say "class code is loaded at the point of first use." This is usually when the first object of that class is constructed, but loading also occurs when a static field or static method is accessed.²
This makes a lot of sense, if you think about the rule that says that a static method can't use non-static methods of the same class. I had this doubt a couple weeks ago when I couldn't understand how, using the Singleton Pattern, you could access the constructor inside the static method that is used to create a new instance of that class. Today I was flipping through the book and I came across this explanation.
It also makes sense in a way that, if the constructor wasn't static, you'd first need an instance of that class to be able to access it, but I guess this could spark up the old discussion about the chicken or the egg.
Hope it helped!
Constructors are neither entirely static (class level) or entirely non-static (instance level).
Unlike instance methods, constructors are not inherited.
Unlike static methods, a constructor can refer to this.
So, why can't you declare a constructor static?
Well, my take is that a (redundant) static keyword would be confusing and would not serve any purpose. Therefore they decided not to allow it.
The explanation that static initialization blocks can be viewed as constructors is (IMO) conceptually wrong. (It is analogous to saying that an instance initialization block is a regular constructor. Which is equally wrong.)
The key distinctions between static initialization and construction1 are:
static initialization happens at an indeterminate time2; there is no equivalent to new for class initialization,
there is no straight-forward way to pass (constructor) parameters to the initialization code
there is no practical way to recover from errors occurring during static initialization.
1 - Hypothetically, if class initialization was explicit, then it would make sense to have static constructors. But the downsize would be that applications would need to explicitly "construct" all of the classes that they used ... which would be horrible.
2 - You have a degree of control if you load a class dynamically, but even then if the class has already been loaded and initialized in the current classloader, then attempting to control initialization will fail.
I do not understand why the main method has to be static.
It has to be if you want the main method to act as an entrypoint for your application.
The problem is that if main was an instance method, then there would need to be an instance of your entrypoint class to call the main method on. But how do you create it? Which constructor would you choose? What if there was no public constructor?
The bottom line is that this is the way that Java was designed ... back in the 1990's ... and so far they have not seen the need to change this.
a) static is belongs to class not object and constrictor is called during the object creation.
b) if we create a constructor as static then it can't be call by subclass as static is accessible only from class not by sub class. So during subclass object creation it can't be call the present class constructor.
c) static members are executed first in the program, so if we declare constructor as static then it will executed before object creation which is oppose the purpose of the constructor.
If we declare constructor as static then it will give compile time error.
If we want to initialize static member then need to use of static block.
I wrote a simple example as an answer to a related question yesterday which may help make things more understandable: what's the point of java constructor?
The point of Static methods is that they can be called without creating an instance of a class, while "normal" instance methods are related to an instance, and can not be called without one.
Since the Main method of the Main class is the entry point of the program, no instance can possibly have been created yet, so naturally, you can not access it via an instance. Therefore, it is Static, so it can be run as the start of the program.
Just take a look on this link, it will definately help you to understand:
Why can't make a constructor static?
AND
Constructor is called at Run-time when we create Objects.
Static is same for all objects but all objects have their own state and properties.
So, if we have had static constructors creation of one object would affect all the other existing objects.
Note: static is class level while constructors related to the objects.
e.g.
public class Foo
{
String name;
int id;
// define constructors
Foo (String name, int id)
{
this.name = name;
this.id = id;
}
p s v m(String[] arg)
{
Foo f1 = new Foo("Amit",001);
Foo f2 = new Foo("Rahul",002);
}
}
If we create static constructor then both objects(f1 also) will contain the last updated value regarding name and id as Rahul and 002.
A constructor cannot be static, because in an OO language, the process for creating an object is as follows:
allocate the object
call the constructor to initialise the newly-allocated object
Constructors are not used anywhere else (and a type-safe language should enforce this), so it follows that a constructor will always be called in a non-static context.
If a constructor were static, it would not receive a reference to the newly-allocated object, and thus would not be able to initialise it.
Thus, a constructor can always be non-static (as it is always called from a non-static context) and must always be non-static (otherwise it would be unable to perform its task).
The main(String[]) method has a specific prototype that is dictated by how the Java runtime environment works. When you invoke java MyApplication from the command line, the Java VM will look for a static main(String[]) method contained in that class in order to execute the application. If that method is not found, then the Java VM can't run the class as an application. That's just how the language is defined. It also means that the Java VM doesn't create an instance of your application class in order to run it.
Now, if you want your class to be usable either as a standalone application or as an instance that's created by something else, then you can have your class implement the Runnable interface, and also provide a main method that executes the run method on a new instance.
public class MyRunnableThing implements Runnable
{
// Define whatever variables your runnable thing needs here as
// private instance fields.
/** Fulfills requirements of Runnable interface. */
public void run()
{
System.out.println( "I'm running..." ) ;
}
/** Also makes the class runnable from the console. */
public static void main( String[] args )
{
MyRunnableThing runMeNow = new MyRunnableThing() ;
runMeNow.run() ;
}
}
Now any class could potentially create an instance of MyRunnableThing and use its run() method to produce the same behavior that would have been seen by executing java MyRunnablething.
See also: Working with Static Constructor in Java. Some highlights from that Q&A:
A constructor is used to create an instance of the class, so it's an instance method, not a static method.
You can create a static method that creates an instance of the class, using the constructor. This is how the trendy new "builder" classes work.
You can create a static method that returns a persistent, unique singleton instance.
If your class has static members, then you can create a static initializer to initialize the values of those members.
The purpose of Constructor is to Construct an Object i.e. to initialize class's instance variables either their default values or by their initialized values. non-static Instance variables can't be accessed by static methods . So constructor is not static.
The method declared as static requires no object creation .As we don't create object for the main method it is declared as static.
constructor is implicitly called to initialize an object, so there is no purpose in having a static constructor.
First, the key word static means that everything marked static must be the class-level thing and belongs to the class only.While constructors belong to object and they may usually be called when we use the new operator.So we now know that a constructor is not even a class property,how could we possibly mark it as static?
Second,static constructor violates the whole purpose of inheritance in java.Every time just before we create an subclass object ,JVM automatically calls the superclass constructor to make it ready for the subclass object to be created.But if we mark the constructor static,the subclass will not be able to access the constructor of its superclass because it's marked static thus belongs to class only.
Java does not permit to declare a constructor as static. Following are the reasons.
Static means for the same class. i.e, static methods cannot be inherited.
With static, "this" reference (keyword) cannot be used. "this" is always linked to an object. A constructor always belongs to some object.
If a constructor is static, an object of subclass cannot access. If static is allowed with constructor, it is accessible within the class but not by subclass.
Static Belongs to Class, Constructor to Object
We know that static methods, block or variables belong to the class. Whereas a Constructor belongs to the object and called when we use the new operator to create an instance. Since a constructor is not class property, it makes sense that it’s not allowed to be static.

Categories