Instance and Constant variables - java

I was wondering is a variable could be both instance and constant? For example would
private final int Min=25;
be both an instance variable and a constant variable?

The Java Language Specification has a chapter on variables.
A variable is a storage location and has an associated type, sometimes
called its compile-time type, that is either a primitive type (§4.2)
or a reference type (§4.3).
There are different types of variables: class, instance, local, method parameter, exception parameter in catch block, constructor parameter, and array components.
There are also final variables which can only be assigned once.
If you declare a non-static field in a class, that is considered an instance variable.
The JLS also says
A variable of primitive type or type String, that is final and
initialized with a compile-time constant expression (§15.28), is
called a constant variable.
So yes, yours is both an instance and constant variable.

From Chapter 4 of the Java Language Specification
In section 4.12.3
An instance variable is a field declared within a class declaration without using the keyword static
In section 4.12.4
A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.
So, yes, this is both a constant variable and an instance variable.
Feel free to use the term "constant variable". It sounds oxymoronic, but the JLS uses it, so you are fine to do so.

Yes, your example would be both an instance and a constant.
There are reasons for having an instance variable that can't be changed.
One is having clear and easy to read code. When you see a variable as final early on, you dont have to worry later on in the program if it is changing value or reference. This allows you to focus on other parts of the program where variables actually are changing.
Take a look at JLS for more info on variables

Instance Variable : an instance variable is a variable defined in a class (i.e. a member variable), for which each object of the class has a separate copy, or instance.
For example :
class MyClass {
int a; // instance variable;
People p; // instance variable;
static int b; // not instance variable. because all instances of class MyClass use same variable b
static People community; // not instance variable with same reason.
}
Constant : a constant is an identifier whose associated value cannot typically be altered by the program during its execution. In Java, there isn't no real constant as C#. In C#, you declare constant is :
// C# Code
const int a = 3; // true
const int a; // wrong. because constant must permently have value. because it cannot have another values in their life.
But in Java, there is just : a variable that you can initialize only one time. and you use it final :
// Java Code
final int a = 3; // true
final int b; // still true. you can declare it later
So. combine above knowledge, you can say your example : private final int Min=25; is both instance variable and "const" variable (java doesn't have const variable, remember)
Hope this help :)

An instance variable is a variable that every instance of a class is going to have its own version of. For example, if you have a Car class, an instance variable of Car might be color. Each time you make a new instance of Car, you can set its color instance variable.
A constant just means that it is unable to change after assignment -- it must also be initialised with a constant expression (thanks David!). So for the Car class, you could instantiate a new Car object with a specific color instance variable. In the Car class code, you could use the final keyword to make the color unchanging after it is set.
Yes, an instance variable can be defined as a constant.

Related

Java - Is it ok to instantiate class objects inside class? [duplicate]

Why can we access a static variable via an object reference in Java, like the code below?
public class Static {
private static String x = "Static variable";
public String getX() {
return this.x; // Case #1
}
public static void main(String[] args) {
Static member = new Static();
System.out.println(member.x); // Case #2
}
}
Generally, public variables can be accessed by everybody, and private variables can only be accessed from within the current instance of the class. In your example you're allowed to access the x variable from the main method, because that method is within the Static class.
If you're wondering why you're allowed to access it from another instance of Static class than the one you're currently in (which generally isn't allowed for private variables), it's simply because static variables don't exist on a per-instance basis, but on a per class basis. This means that the same static variable of A can be accessed from all instances of A.
If this wasn't the case, nobody would be able to access the private static variable at all, since it doesn't belong to one instance, but them all.
The reason that it is allowed is that the JLS says it is. The specific sections that allows this are JLS 6.5.6.2 (for the member.x cases) and JLS 15.11.1 (in both cases). The latter says:
If the field is static:
If the field is a non-blank final field, then the result is the value of the specified class variable in the class or interface that is the type of the Primary expression.
If the field is not final, or is a blank final and the field access occurs in a class variable initializer (§8.3.2) or static initializer (§8.7), then the result is a variable, namely, the specified class variable in the class that is the type of the Primary expression.
Why are these allowed by the JLS?
Frankly, I don't know. I can't think of any good reasons to allow them.
Either way, using a reference or this to access a static variable is a bad idea because most programmers are likely to be mislead into thinking that you are using an instance field. That is a strong reason to not use this feature of Java.
In your first and second cases you should reference the variable as x or Static.x rather than member.x. (I prefer Static.x.)
It is not best practice to reference a static variable in that way.
However your question was why is it allowed? I would guess the answer is to that a developer can change an instance member (field or variable) to a static member without having to change all the references to that member.
This is especially true in multi-developer environments. Otherwise your code may fail to compile just because your partner changed some instance variables to static variables.
static variables are otherwise called as class variables, because they are available to each object of that class.
As member is an object of the class Static, so you can access all static as wll as non static variables of Static class through member object.
The non-static member is instance member. The static member(class wide) could not access instance members because, there are no way to determine which instance owns any specific non-static members.
The instance object could always refers to static members as it belongs to class which global(shared) to its instances.
This logically makes sense although it is not interesting practice. Static variable is usually for enforcing single declaration of variable during instantiation. Object is a new copy of Class with other name. Even though object is new copy of class it is still with characteristics of the (uninstantiated) Class (first invisible instance). Therefore new object also has that static members pointing to the original copy. Thing to note is: New instance of StackOverflow is also StackOverflow.

Java variable initialization different ways of handling?

I just found that Java handles variable initialization in different ways.
Case-1:
class A {
boolean x;
public static void main(String[] args) {
A a = new A();
System.out.println(a.x);
}
}
When I ran above program it shows like "false" as output. But now I am posting other piece of code:
Case-2:
class A {
public static void main(String[] args) {
boolean x;
System.out.println(x);
}
}
Now, above piece of code shows that
java.lang.Error: Unresolved compilation problem:
The local variable x may not have been initialized
Why the same thing is handled in very different ways?
Thanks in advance!
From the Oracle documentation on Java Primitive Data Types:
Local variables are slightly different; the compiler never assigns a
default value to an uninitialized local variable. If you cannot
initialize your local variable where it is declared, make sure to
assign it a value before you attempt to use it. Accessing an
uninitialized local variable will result in a compile-time error.
So this is an interesting nuance. If a primitive type variable is locally declared, you must specify a value for it.
There are three distinct types of variables:
static variables - within class;
member variables - within object
local variables - having scope limited to a function or block of code
Assumming the variables are not final.
The first two default to 0 or false (when var is a primitive) or
null (when var is an object) when accessed for read. The last one must be set to a value prior to reading, otherwise the code will not compile.
All of variable types (local, member, static) must be assigned a particular value if defined as final. Such Initialisation of static final variable can be an inline assignment to a value or it can be done in static initialisation block. Initialisation of final member variables can be done inline, within Initialisation block or within object's constructor (most common - best practice).
Final local variables initialized inline. There is also "effectively final" variable that is inferred by compiler when it sees that variable will not be changed. Final variables allow compiler to treat and optimize handling of data.
Thats just a couple of basic items to start with. Hope it is helpful.
Cheers.
If this question is about why local variables are treated different from non-final member variables: in the example above I do not see any use do declare boolean x; instead of boolean x = false;, but the last one makes the intent of the programmer clear. Also you are allowed to declare boolean x; if you initialize x later. Here the compiler error you get is helpful so you don't forget to initialize it in some rare edge case. The compiler couldn't check that if it would be initialized by default.
It's also common to have code like
int i;
if (a > b)
i = 8; // loong code
else
i = 42; // loong code
Initializing i would be useless here.
Static and non-static members (non final) are different because the compiler always nulls all fields before running initializers and constructors. Not initializing them to 0 manually is a slight performance improvement.
Explanation
Your two examples use different kinds of variables:
a field (also called instance variable, or member)
a local variable
You can only use a variable if it has a value / refers to an instance. For fields, if you do not explicitly assign a value, they are defaulted. That is not the case for local variables, thus the error.
The default value is null for objects and special values for primitives, like 0, 0.0, false and similar.
Java Language Specification
The JLS clearly defines this behavior and explains how it works. Take a look at chapter 4.12.5 Initial Values of Variables where it states (relevant excerpts):
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2):
For type boolean, the default value is false.
A local variable (§14.4, §14.14) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26), in a way that can be verified using the rules for definite assignment (§16 (Definite Assignment)).

Can we say that the reference variable pointing to an immutable object is a constant variable?

I have a doubt from one of the answers in stackoverflow to the following question:
How many String objects are created by the following code?
String x = new String("xyz");
String y = "abc";
x = x + y;
In Stephen's answer he mentioned x and y are not constant variables.
My doubt- String is a final class, and it's instance will be a constant because String is an immutable class. Why is the reference variable of this constant class not a constant variable? - I do agree with Stephen though as x = x + y; points at "xyzabc" created in the heap memory.
There are a few concepts that you need to understand.
Marking a class as final does not make it immutable. It just makes it un-inheritable.
JLS §8.1.1.2
A class can be declared final if its definition is complete and no subclasses are desired or required.
It is a compile-time error if the name of a final class appears in the extends clause (§8.1.4) of another class declaration; this implies that a final class cannot have any subclasses.
A class is said to be immutable when the values that it stores cannot be changed after initialisation.
A constant variable is a variable marked with final.
JLS §4.12.4
A variable can be declared final. A final variable may only be assigned to once. Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.
It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.
x and y here are not constants because they are not marked final. That's it.
"But strings can't change, so they are constants, right?" you might ask.
String objects themselves can't change, but string variables can. I'll show you:
String s = "Hello";
s = "Goodbye";
The variable's value is changed so that it refers to another string. The original string "Hello" is not changed.

Java Constructors- Assigning value to variable

Is there a difference between assigning values to variables outside of any method, and assigning these values within a constructor?
Looking at Oracle's Java tutorial, they have:
public class Bicycle {
int cadence = 0;
int speed = 0;
int gear = 1;
void changeCadence(int newValue) {
cadence = newValue;
}
is this any different from saying/why didn't they just say:
Bicycle(){
int cadence = 0;
}
If you declare the variable in your constructor, it will be local to the constructor and not visible anywhere else in your class.
If you declare a variable inside a constructor, this variable can only be accessed inside this constructor. But, you can create a variable on your class, and access it on your constructor or method.
Well if you define a variable in a constructor, it is local to the constructor. But a variable in the class is part of class' state.
But if you mean:
class A {
int i = 1;
...
}
vs
class B {
int i;
B() {
i = 1;
}
...
}
the difference is: in the first case, the default value of i is 1, in all instances, but in second case the default value of i is 1 if the shown constructor is called, maybe in other constructors other default value be something else (or 0 if nothing is assigned to i).
When you create object instance, global variables will be initialized. You can (but not have to) change some of them in constructor.
I think you mean
Bicycle() {
cadence = 0;
}
In the constructor : it will be Local variable
Java contains the following types of variables:
Instance Variables (Non-static fields): In object oriented programming, objects store their individual states in the "non-static fields" that is declared without the static keyword. Each object of the class has its own set of values for these non-static variables so we can say that these are related to objects (instances of the class).Hence these variables are also known as instance variables. These variables take default values if not initialized.
Class Variables (Static fields): These are collectively related to a class and none of the object can claim them its sole-proprietor . The variables defined with static keyword are shared by all objects. Here Objects do not store an individual value but they are forced to share it among themselves. These variables are declared as "static fields" using the static keyword. Always the same set of values is shared among different objects of the same class. So these variables are like global variables which are same for all objects of the class. These variables take default values if not initialized.
Local Variables: The variables defined in a method or block of code is called local variables. These variables can be accessed within a method or block of code only. These variables don't take default values if not initialized. These values are required to be initialized before using them.
Parameters: Parameters or arguments are variables used in method declarations.
The constructor is like any other method. Variables that are declared inside it are available only within it, and they'll get destroyed when you go out of scope.
The difference in this case is that you are not only assigning the variable in the constructor (in the second case). You are also declaring it there. Thus, the variable is local to the constructor and not visible from outside.
I think your question is: If we can give a default value to the variable(of a class) directly, why to give it inside a constructor instead. If that's the question, then I think its because the values in the variable would be available even when the objects are not initialized which is not a healthy practice and does not make much sense. Instead, giving values inside a constructor would not only be hidden but would also obey oops rules for java.

Java: Memory usage of the final keyword?

When you declare a final variable (constant) in a class, for example:
private static final int MyVar = 255;
How much memory will this require if I have 100,000 instances of the class which declared this?
Will it link the variable to the class and thus have 1*MyVar memory usage (disregarding internal pointers), or will it link to the instance of this variable and create 100,000*MyVar copies of this variable?
Unbelievably fast response! The consensus seems to be that if a variable is both static and final then it will require 1*MyVar. Thanks all!
The final keyword is irrelevant to the amount of memory used, since it only means that you can't change the value of the variable.
However, since the variable is declared static, there will be only one such variable that belongs to the class and not to a specific instance.
Taken from here:
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 . 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, a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
There will be only 1*MyVar memory usage because it is declared as static.
The static declaration means it will only have one instance for that class and it's subclasses (unless they override MyVar).
An int is a 32-bit signed 2's complement integer primitive, so it takes 4 bytes to hold it, if your example wasn't using static you'd just multiply that by the number of instances you have (for your example of 100,000 instances that's 0.38 of a megabyte - for the field alone, extra overhead for actual classes).
The final modifier on a field means it cannot be repointed to another value (whereas final on a class of method means it cannot be overridden).
It's static and thus class scope -> 1.
Edit: actually, it depends on the class loaders. In the general case you have one copy of the class but if you have multiple class loaders/class repositories (might be the case in application servers etc.) you could end up with more.
In addition to the fact that static fields belong to their classes, and thus there is only one instance of static varaible per class (and per classloader), it's important to understand that static final variables initialized by compile-time constant expressions are inlined into classes that use them.
JLS §13.1 The Form of a Binary:
References to fields that are constant variables (§4.12.4) are resolved at compile time to the constant value that is denoted. No reference to such a constant field should be present in the code in a binary file (except in the class or interface containing the constant field, which will have code to initialize it), and such constant fields must always appear to have been initialized; the default initial value for the type of such a field must never be observed.
So, in practice, the instance of static final variable that belong to its class is not the only instance of value of that variable - there are other instances of that value inlined into constant pools (or code) of classes that use the variable in question.
class Foo {
public static final String S = "Hello, world!";
}
class Bar {
public static void main(String[] args) {
// No real access to class Foo here
// String "Hello, world!" is inlined into the constant pool of class Bar
String s = Foo.S;
System.out.println(s);
}
}
In practice it means that if you change the value of Foo.S in class Foo, but don't recompile class Bar, class Bar will print the old value of Foo.S.
static means you will have only one instatnce
final just means, that you can't reassign that value.
The crucial part here is that you declared the variable as static because static variables are shared among all instances of the class, thus requiring only as much space as one instance of the variable. Declaring a variable final makes it immutable outside its declaration or constructor.
final makes is 1*instances memory usage.
However, static makes it simply 1.
The keyword "final" helps you to declare a constant with a specific amount of memory, where as the keyword "static" as its prefix will gives a single instance of this constant, what ever be the amount of memory consumed...!!!
Static means, one instance per class, static variable created once and can be shared between different object.
Final variable, once value is initialized it can't be changed. Final static variable use to create constant (Immutable) and refer directly without using the object.
It's static, so there will be only one instance created, so however many bytes are required to hold one int primitive will be allocated
You will have one instance per class. If you have the class loaded more than once (in different class loaders) it will be loaded once per class loader which loads it.
BTW: Memory is surprising cheap these days. Even if there was a copy per instance, the time it takes you to ask the question is worth more than the memory you save. You should make it static final for clarity rather than performance. Clearer code is easier to maintain and is often more efficient as well.

Categories

Resources