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.
Related
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.
I have a class A. I define another class B within a method (even main) of the class A and class B can access all the variables within the scope of the method it is defined in. What is the terminology for such classes (as B)? Some people have been saying Nested classes or Inner classes but IIRC, those are the classes where they have another class as their data members (kinda like composition in C++).
The second part of my question is that some people have been saying that when you have a class defined within a method of another class, then the variables of the first class (A) that are accessed by the later class (B) need to be declared final. Is this to be followed strictly and why so?
According to the Java Language Specification these are "local classes":
A local class is a nested class (§8 (Classes)) that is not a member of
any class and that has a name (§6.2, §6.7).
or "anonymous [inner] classes", which are just the ones that don't have a name (e.g. Interface x = new Interface() { ...).
These are special cases of inner classes which is generally what I've heard people refer to them as.
As for your second question, "Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted." So it is a compile-time error if you try to access non-final local variables. Obviously this part must be followed strictly if you want your class to compile.
I have not personally heard the advice that you should not access non-final fields of the enclosing class, and I'm pretty sure it's allowed. While arguments could be made that fields should be final unless they can't be, I don't see any stylistic reason this should be more important in inner classes. There is a technical difference that accessing a field from an inner class may cause the compiler to create and call synthetic getters and setters, but this is generally a minor performance concern.
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.
Although, this is a very basic code, it seems there is something fundamentally flawed in Java, or the JVM used by the Eclipse IDE I have used to run the code.
The code runs even though it should not (I think)! The code in A.java simply displays "Hello, I am A!"
Here it is:
import java.lang.*;
import java.util.*;
class A {
private void methodA() {System.out.println("Hello, I am A!");}
public static void main(String[] args) {
A a = new A();
a.methodA(); }
}
I do not understand why, after creating an instance of class A, main() succeeds in running a private method of class A on that instance. Yes, the main method belongs to class A, but it is not accessing the private method from inside the current object in the context of the "this" reference. In fact, since it is a static method, it cannot access non-static members from within the class. Instead of main(), a non-static member method could have invoked methodA() from inside only. But that is another issue since I have not defined any non-static second method.
Now that the inside-view is talked about, let's come back to the point, the outside-view. As you can see, main() attempts to invoke methodA from outside the object and succeeds! Why isn't private getting treated as private?
I am pulling my hair....
Anyone, please reply...
Yes, the main method belongs to class A, but it is not accessing the private method from inside the current object in the context of the "this" reference.
That doesn't matter. That's just not the model of accessibility that Java uses. What's important is the class in which the code is written, not whether it's accessing members in the same object.
This is very useful, as otherwise (for example) it would be impossible to implement an equals method using private members of both classes.
This may not be how you would have chosen to specify the language, but it is how Java is specified. See JLS 6.6.1 for details of accessibility. In particular:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Note that protected access is slightly odd here - a protected instance member of class SuperClass can only be accessed within code in SubClass via an expression of either SubClass or a further subclass. But it still doesn't have to be "the same" object.
private modifer
Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself.
private means "private to the class". Not "private to the instance".
That's what allows implementing things like static factory methods calling private constructors, or equals() or compareTo() methods comparing private fields of objects of the same class, or copy constructors, etc.
Private members of enclosing classes are also accessible from inner classes of this enclosing class, and vice-versa.
After the technically correct answers here's my two cents why I think it is quite reasonable to implement private that way:
As I see it the main reason that private methods and attributes exists is "implementation hiding". You are declaring "Don't use this method from outside my class(!), since it might change or disapear anytime I like". So it makes sense to disallow access from outside the class. But if I'm accessing it from another object of the same class I and make any implementation changes I'm well aware of the changes and the accesses of the private members and can act accordingly.
Another thing to think about:
If class B extends class A, then any B-object also is an A-object, but it can't access the private A-methods. Why would that be if private methods were private to the object?
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.