Difference between the terms "Instance variable" and "variables declared in Interfaces" - java

I was reading about Interfaces in a Book and I came upon this Line that confused me.
Interfaces are syntactically similar to classes, but they lack instance variables.
As far as I know about Interfaces, we can define variables inside an Interface which are by default final.
My question is, What does that Line mean? and What is the Difference between an Instance Variable and the Variable defined in the Interface??

My question is, What does that Line mean?
Amongst other things, it means the book's terminology is off. By "instance variable," they mean "instance field."
An instance field is a field that is specific to an individual instance of a class. For example:
class Foo {
// Instance field:
private int bar;
// Static field:
public static final int staticBar;
}
The field bar is per-instance, not class-wide. The field staticBar is class-wide (a static field, sometimes called a "class field").
Interfaces don't have instance fields. They do have static fields. When you do this:
interface FooInterface {
int staticBar;
}
staticBar is automatically declared public, static, and final (per JLS §9.3). So that staticBar is roughly equivalent to the one on our Foo class before.

This means you cant have instance variable but a constant static final variable within an interface as per JLS. For e.g.
interface MyIface {
public static final int MY_CONSTANT = 1;
}
And access it using interface name like:
int variable = MyIface.MY_CONSTANT;

Related

Private enums and static fields in the enclosing class

I understand why an enum constructor cannot access static fields
and methods within the enum itself, and why the same is allowed
for in classes. Se for an example the following code,
import java.util.ArrayList;
import java.util.List;
public enum Foo {
A("Some string"),
B("Some other string"),
;
static List<String> list = new ArrayList<>();
Foo(String description) {
list.add(description);
}
}
This code causes a compile-time error, illegal reference to static field from initializer.
Relevant background
The enum constructor is called before the static fields have all
been initialized. In the above example this means that list is not yet initialized. This is because static fields are initialized in textual
order (section 12.4.2)
Next, execute either the class variable initializers and static
initializers of the class, or the field initializers of the
interface, in textual order, as though they were a single block.
(emphasis mine)
and since the enum values themselves always precede any other
fields, including static fields, they are not available to the
enum constructor, i.e. no static fields may preceed the enum
values A, and B.
Question
However, and here is my question, why is it that a "private" (enclosed inside a class) enum
can access static fields of its enclosing class,
regardless of whether or not the enum appears before --- or ---
after the static fields? In particular, where in the Java-specification is this specified?
See the below code for reference
import java.util.ArrayList;
import java.util.List;
public class Bar {
static List<String> first = new ArrayList<>();
enum Baz {
A("Some string"),
B("Some other string"),
;
Baz(String description) {
// Can access static fields from before the enum
first.add(description);
// Can access static fields from _after_ the enum
second.add(description);
}
}
static List<String> second = new ArrayList<>();
}
This is a bit all over the place in the JLS. The When Initialization Occurs chapter states
The intent is that a class or interface type has a set of initializers
that put it in a consistent state, and that this state is the first
state that is observed by other classes. The static initializers and
class variable initializers are executed in textual order, and may not
refer to class variables declared in the class whose declarations
appear textually after the use, even though these class variables are
in scope (§8.3.3). This restriction is designed to detect, at compile
time, most circular or otherwise malformed initializations.
That bold snippet refers to the class directly containing the access.
enum types are defined in the Java Language Specification, here
An enum declaration specifies a new enum type, a special kind of class type.
The fields you access in the Baz constructor
Baz(String description) {
// Can access static fields from before the enum
first.add(description);
// Can access static fields from _after_ the enum
second.add(description);
}
are not class variables declared in the class, the enum type Baz. The access is therefore allowed.
We can go even deeper into the detailed class initialization procedure, which explains that each class (class, interface, enum) is initialized independently. However, we can create an example that sees yet-to-be-initialized values
public class Example {
public static void main(String[] args) throws Exception {
new Bar();
}
}
class Bar {
static Foo foo = Foo.A;
static Integer max = 42;
enum Foo {
A;
Foo() {
System.out.println(max);
}
}
}
This will print null. The access to max is allowed in the enum type's constructor although our program execution reached the access before max was initialized. The JLS warns against this
The fact that initialization code is unrestricted allows examples to
be constructed where the value of a class variable can be observed
when it still has its initial default value, before its initializing
expression is evaluated, but such examples are rare in practice. (Such
examples can be also constructed for instance variable initialization
(§12.5).) The full power of the Java programming language is available
in these initializers; programmers must exercise some care.
Your original Foo example introduces an extra rule, defined in the chapter on Enum Body Declarations .
It is a compile-time error to reference a static field of an enum type
from constructors, instance initializers, or instance variable
initializer expressions of the enum type, unless the field is a
constant variable (§4.12.4).
That rule blocks your Foo snippet from compiling.
enum constants translate to public static final fields. These appear textually first in the enum type definition and are therefore initialized first. Their initialization involves the constructor. The rules exists to prevent the constructor from seeing uninitialized values of other class variables that will necessarily be initialized later.
The position of nested classes has no meaning. You can refer to the nested class before (earlier in source text) it is declared, same as you can refer to methods before they are declared.
This is because the nested class is actually an independent class. The enclosing class and the nested class are independently initialized.
So, lets say the neither Bar nor Baz are initialized.
If some code needs Bar then Bar will be initialized. Baz will not be initialized at that time, since Bar does not refer to Baz.
If however some code needs Baz (none of them initialized yet), then Baz initialization begins. When the Baz constructor for A begins running, Bar is still not initialized. The first line then needs Bar, and Bar initialization begins. Bar initialization completes normally, in full, before the first.add(description) statement is executed. The second statement can also be executed, because Bar is fully initialized.
As you can see, there is no initialization order conflict. Bar will be fully initialized, and therefore fully available, for use by the Baz constructor.
To see the sequence of events, I added some print statements:
public class Test {
public static void main(String[] args) {
Bar.Baz x = Bar.Baz.A;
}
}
class Bar {
static { System.out.println("Bar initializing..."); }
static List<String> first = new ArrayList<>();
enum Baz {
A("Some string"),
B("Some other string"),
;
static { System.out.println("Baz initializing..."); }
Baz(String description) {
System.out.println(getClass() + "." + name() + " in construction...");
// Can access static fields from before the enum
first.add(description);
// Can access static fields from _after_ the enum
second.add(description);
System.out.println(getClass() + "." + name() + " constructed...");
}
static { System.out.println("Baz initialized..."); }
}
static List<String> second = new ArrayList<>();
static { System.out.println("Bar initialized"); }
}
Output
class Bar$Baz.A in construction...
Bar initializing...
Bar initialized
class Bar$Baz.A constructed...
class Bar$Baz.B in construction...
class Bar$Baz.B constructed...
Baz initializing...
Baz initialized...
As you can see, Bar will starting initializing once used inside the Baz constructor, and it will be completely initialized at that time. Therefore it is fully available for Baz to use, regardless of source text position.
You can also see that Baz static initializers don't run until after the enums have been constructed, which is of course why you can't reference static members from the constructor.

The field is ambiguous while it is clearly hidden

I know and fully agree that sharing constants through interfaces is considered as a bad practice, but I didn't choose this implementation. Whatever:
interface SuperClassConstants {
public static final String CONSTANT = "super";
}
interface SubClassConstants extends SuperClassConstants {
public static final String CONSTANT = "sub";
}
class SuperClass implements SuperClassConstants {
}
class SubClass extends SuperClass implements SubClassConstants {
public SubClass() {
System.out.println(CONSTANT);
// The field CONSTANT is ambiguous
}
}
Why ambiguous? Isn't the constant hidden? I thought Java would have understood I was expecting "sub"...
As per the JLS 9.3:
If two fields with the same name are inherited by an interface because, for example, two of its direct superinterfaces declare fields with that name, then a single ambiguous member results. Any use of this ambiguous member will result in a compile-time error.
The field CONSTANT in SubClassConstants has hidden the CONSTANT of SuperClassConstants. But the class SubClass has access to both the CONSTANT as it virtually implements both the interfaces.
You can remove the ambiguity by specifying the Interface name :
System.out.println(SubClassConstants.CONSTANT);
Also read JLS 6.5.6.1:
If an expression name consists of a single Identifier, then there must be exactly one declaration denoting either a local variable, parameter, or field visible (§6.4.1) at the point at which the Identifier occurs. Otherwise, a compile-time error occurs.

Interface Variables

public interface A
{
public final int a = 0;
}
Many books say that all variables (constants) in an interface are implicitly public static final yet when I type the above statement explicitly but do not include the keyword static it compiles with no errors and can be referenced by the static way, A.a which indicates that it is still static.
Is it static or not, as to me it has to be since you cannot instantiate an interface, as if you had this "instance" variable then you could therefore never access the data member "a" as it is a non-static field.
Many books say that all variables (constants) in an interface are implicitly public static final
Yes, and what you're observing is exactly consistent with that. The key word is implicitly: it is a static variable whether or not you write the word static.

Difference between Static and final?

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

Assigning a final field in Java

I am working on a class that has some fields with final access modifier like: final textField and I am allowed to assign to them forsome reason. When I change them to static final I can no longer assign anything to them (it complains that they are final like it should have done in the first place). Any ideas why this is happening ?
Example for the first case:
final LabelField label_title;
label_title = new LabelField(
"Press the button to launch the speed test",
LabelField.FIELD_HCENTER);
You can assign final fields in constructor, you can't assign static final fields in a constructor. You shouldn't change static fields in a constructor in any case.
When a field is defined as final, it has to be initialised when the object is constructed, i.e. you're allowed to assign value to it inside a constructor.
A static field belongs to the class itself, i.e. one per class. A static final field is therefore not assignable in the constructor which is one per object.
Hope it makes sense to you!
The value of final members can't be changed. But it is allowed to initialize a final instance field in the constructor. This is not allowed for class members. The next snippets shows what's allowed and what's not allowed:
public class Final {
final static Integer INT1; // compile error
final static Integer INT2 = new Integer(2);
final Integer int3;
final Integer int4 = new Integer(4);
public Final() {
int3 = new Integer(3);
int3 = new Integer(3); // compile error
}
}
From the JLS - final fields: -
A field can be declared final (§4.12.4). Both class and instance
variables (static and non-static fields) may be declared final.
It is a compile-time error if a blank final (§4.12.4) class variable
is not definitely assigned (§16.8) by a static initializer (§8.7) of
the class in which it is declared.
A blank final instance variable must be definitely assigned (§16.9) at
the end of every constructor (§8.8) of the class in which it is
declared; otherwise a compile-time error occurs.
So, JLS clearly specifies that you should assign your static final fields in static initializer block. You can't assign them in any constructor.
So, if you have a static final field, you should either initialize them in place, or you can use a Static Initializer Block to initialize them.
Moreover, you can assign your final fields in constructor, provided you don't change the assignment later on anywhere..
A static field belongs to the class, which is (should be) initialized right after the class is loaded, and that is when it must be initialized (the value needs to be assigned) if it is final.
Constructor is called when someone needs to instantiate the class. Now if you change the value of that static final field in the constructor means that you are trying to change (or re-assign) it's value.
But doing that in a static initializer (static { /* assign value here */ }) should be fine, which is meant for initialization of the class.

Categories

Resources