I am stuck at the below concept of initialization of java class and interface :
I read the following sentence in the below mentioned book :
An interface is initialized only because a non-constant field declared by the interface is used, never because a subinterface or class that implements the interface needs to be initialized.
But that isn't the case when we initialise any java class.
Thus, initialization of a class requires prior initialization of all its superclasses, but not its superinterfaces.
Initialization of an interface does not require initialization of its superinterfaces.
My question is Why is this so ?
Any help would be greatly appreciated !
Thanks
PS : Book - "Inside the Java Virtual Machine" by Bill Venners (Chapter 7 - LifeTime of a class )
The only things you can declare in an interface are method signatures and constant fields. The latter can be initialized using constant values (i.e. string literals, integers, etc., possibly in some combination) or using non-constant values (i.e. method calls). Thus if an interface doesn't have any non-constant fields, no initialization is required -- everything is known at compile time. If there are non-constant fields that are used by the program, initialization code must be run to ensure those fields are assigned a value.
Hope that helps.
P.S.: That chapter is available online here if anyone wants to read it in full.
To cite the Java language specification §12.4.1:
A class or interface type T will be
initialized immediately before the
first occurrence of any one of the
following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the reference to the field is not
a compile-time constant (§15.28).
References to compile-time constants
must be resolved at compile time to a
copy of the compile-time constant
value, so uses of such a field never
cause initialization.
Invocation of certain reflective
methods in class Class and in package
java.lang.reflect also causes class or
interface initialization. A class or
interface will not be initialized
under any other circumstance.
The intent here 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.
Interesting. Let's see why superclass must be initialized before subclass.
class A
static x = DB.insert(1,...);
class B extends A
static y = DB.select(1);
The static initializer of a superclass can cause some side effects that the compiler cannot see, and the subclass may depend on such side effects.
However the same argument can apply to super interfaces. I don't see a hard reason why Java doesn't initialize super interfaces eagerly. Soft reasons are anybody's guess.
Give the rules as they are, we must be careful with field initialization in interfaces:
better not have any fields in an interface
otherwise, fields better be compile time constant only
otherwise, field initialization better not have any side effect.
otherwise, side effect must be only accessible through the field itself
Related
Why can't constructors be final, static, or abstract in Java?
For instance, can you explain to me why this is not valid?
public class K {
abstract public K() {
// ...
}
}
When you set a method as final it means: "I don't want any class override it." But according to the Java Language Specification:
JLS 8.8 - "Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding."
When you set a method as abstract it means: "This method doesn't have a body and it should be implemented in a child class." But the constructor is called implicitly when the new keyword is used so it can't lack a body.
When you set a method as static it means: "This method belongs to the class, not a particular object." But the constructor is implicitly called to initialize an object, so there is no purpose in having a static constructor.
The question really is why you want constructor to be static or abstract or final.
Constructors aren't inherited so can't be overridden so whats the use
to have final constructor
Constructor is called automatically when an instance of the class is
created, it has access to instance fields of the class. What will be
the use of a static constructor.
Constructor can't be overridden so what will you do with an abstract
constructor.
A Java constructor is implicitly final, the static / non-static aspects of its semantics are implicit1, and it is meaningless for a Java constructor to be abstract.
This means that the final and static modifiers would be redundant, and the abstract keyword would have no meaning at all.
Naturally, the Java designers didn't see in any point in allowing redundant and/or meaningless access modifiers on constructors ... so these are not allowed by the Java grammar.
Aside: It is a shame that they didn't make the same design call for interface methods where the public and abstract modifiers are also redundant, but allowed anyway. Perhaps there is some (ancient) historical reason for this. But either way, it cannot be fixed without rendering (probably) millions of existing Java programs uncompilable.
1 - Actually, constructors have a mixture of static and non-static semantics. You can't "call" a constructor on an instance, and it they are not inherited, or overridable. This is similar to the way static methods work. On the other hand, the body of a constructor can refer to this, and call instance methods ... like an instance method. And then there is constructor chaining, which is unique to constructors. But the real point is that these semantics are fixed, and there is no point allowing a redundant and probably confusing static modifier.
public constructor: Objects can be created anywhere.
default constructor: Objects can be created only in the same package.
protected constructor: Objects can be created by classes outside the package only if it's a subclass.
private constructor: Object can only be created inside the class (e.g., when implementing a singleton).
The static, final and abstract keywords are not meaningful for a constructor because:
static members belong to a class, but the constructor is needed to create an object.
An abstract class is a partially implemented class, which contains abstract methods to be implemented in child class.
final restricts modification: variables become constant, methods can't be overridden, and classes can't be inherited.
Final: Because you can't overwrite/extend a constructor anyway. You can extend a class (to prevent that you make it final) or overwrite a method (to prevent that you make it final), but there is nothing like this for constructors.
Static: If you look at the execution a constructor is not static (it can access instance fields), if you look at the caller side it is (kind of) static (you call it without having an instance. Its hard to imagine a constructor being completely static or not static and without having a semantic separation between those two things it doesn't make sense to distinguish them with a modifier.
Abstract: Abstract makes only sense in the presence of overwriting/extension, so the same argument as for 'final' applies
No Constructors can NEVER be declared as final. Your compiler will always give an error of the type "modifier final not allowed"
Final, when applied to methods, means that the method cannot be overridden in a subclass.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
No Constructors can NEVER be declared final. YOur compiler will always give an error of the type "modifer final not allowed"
Check the JLS Section 8.8.3 (The JLS & API docs should be some of your primary sources of information).
JLS section 8 mentions this.
Constructors (§8.8) are similar to methods, but cannot be invoked
directly by a method call; they are used to initialize new class
instances. Like methods, they may be overloaded (§8.8.8).
But constructors per say are not regular methods. They can't be compared as such.
why constructor can not be static and final are well defined in above answers.
Abstract: "Abstract" means no implementation . and it can only be implemented via inheritance. So when we extends some class, all of parent class members are inherited in sub-class(child class) except "Constructor". So, lets suppose, you some how manage to declare constructor "Abstract", than how can you give its implementation in sub class, when constructor does not get inherit in child-class?
that's why constructor can't be
abstract .
lets see first
final public K(){
*above the modifier final is restrict 'cause if it final then some situation where in some other class or same class only we will override it so thats not gonna happen here proximately not final
eg:
we want public void(int i,String name){
//this code not allowed
let static,, static itz all about class level but we create the object based constructor by using 'new' keyword so,,,,,, thatsall
abstract itz worst about here not at 'cause not have any abstract method or any declared method
Unfortunately in PHP the compiler does not raise any issue for both abstract and final constructor.
<?php
abstract class AbstractClass
{
public abstract function __construct();
}
class NormalClass
{
public final function __construct() {
echo "Final constructor in a normal class!";
}
}
In PHP static constructor is not allowed and will raise fatal exception.
Here in AbstractClass obviously a constructor either can be declared as abstract plus not implemented or it can be declared as something among (final, public, private, protected) plus a function body.
Some other related facts on PHP:
In PHP having multiple constructor __construct() is not possible.
In PHP a constructor __construct() can be declared as abstract, final, public, private and protected!
This code was tested and stood true for in PHP versions from 5.6 up to 7.4!
I had a test today and one of the questions was about using a virtual method in C++ constructor. I failed this question, I answered that there shouldn't be any problem, however after reading this I found out I was wrong.
So I understand that the reason for not allowing that is because the derived object is not fully initialized and therefore calling it's virtual method can cause invalid consequences.
My question how was it solved in Java/C# ? I know that I can call derived method in my base constructor, I would assume that these languages have exactly the same problem.
Java has a very different object model from C++. In Java, you cannot have variables which are objects of class type -- instead, you can only ever have references to objects (of class type). Therefore, all members of a class (which are only references) start out trivially as null until the entire derived object has been set up in memory. Only then do the constructors run. Thus by the time a base constructor calls a virtual function, even if that function is overridden, the overridden function can at least correctly refer to members of the derived class. (Those members may not themselves be assigned yet, but at least they exist.)
(If it helps, you can also consider that every class without final members in Java is technically default-constructible, at least in principle: Unlike in C++, Java has no such things as constants or references (which must be initialized in C++), and in fact there are no initializer lists at all. Variables in Java simply don't need to be initialized. They're either primitives which start as 0, or class type references which start as null. One exception comes from non-static final class members, which cannot be rebound and must actually be "initialized" by having precisely one assignment statement somewhere in every constructor [thanks to #josefx for pointing this out!].)
understand that the reason for not allowing that is because the derived object is not fully initialized and therefore calling it's virtual method can cause invalid consequences
Wrong. C++ will call the base class's implementation of the method, not the derived class's. There are no 'invalid consequences'. The only valid reason for avoiding the construct is that the behavior sometimes comes as a surprise.
This is different from Java because Java calls the derived class's implementation.
In C++ every polymorphic class( class that has at least one virtual function ) has a hidden pointer at start of it( usually named v-table or something like that ) that will be initialized to the virtual table( an array of functions that point to the body of each virtual function ) of that class and when you call a virtual function C++ simply call ((v-table*)class)[index of your function]( function-parameters ), so if you call a virtual function in base class constructor v-table point to virtual table of the base class since your class is base and it still need some initialization to become child and as a result you will call implementation of the function from base not from child and if this is a pure virtual function you will get an access violation.
but in java this is not something like this, in java whole the class is something like std::map<std::string, JValue> in this case JValue is some variant type( for example a union or boost::variant ) when you call a function in constructor of base it will find function name in the map and call it, it is still not the value from the child but you can still call it and if you changed it in the prototype, since prototype created before your constructor you can successfully call function from child but if function required some initialization from constructor of the child you still get error or an invalid result.
so in general it is not a good practice to call a function from child( for example a virtual function ) in base class. if your class need to do this add an initialize method and call it from constructor of your child class.
Every Java constructor looks like this:
class Foo extends Bar {
Foo() {
super(); // creates Bar
// do things
}
}
So if you place code working on derived methods in do things, seems to be logic, that this base object was initialized properly, after calling its constructor in super();
I think that Java/C# avoid this problem by constructing from derived class backwards rather than in C++ from base class forwards.
Java implicitly calls super() in a classes constructor so by the time the first line of written code in a derived class constructor is called all the constructors of all inherited classes are guaranteed to have been called and so the new instance will have been completely initialised.
I think also in C++ a new instance of a class begins life as the base class and gets "upgraded" to the final class type as we move down the inheritance chain. This means that when you call a virtual function in the constructor you'll actually be calling the version of that function for the base class.
In Java and presumably C# a new instance starts life as the required class type so the correct version of the virtual method will be called.
Java does not entirely avoid the problem.
An overridden method called from a superclass constructor that depends on fields of the subclass will be called before those fields have been initialized.
If you're in control of the entire class hierarchy, you can of course just make sure your overrides don't depend on subclass fields. But it's safer to just not call virtual methods from constructors.
As we use "default" keyword as a access specifier, and it can be used in switch statements as well with complete different purpose, So i was curious that is there any other keywords in java which can be used in more then one purposes
The "default" in the case of access modifier isn't a keyword - you don't write:
default void doSomething()
However, when specifying the default value of an attribute of annotations - it is.
switch (a) {
default: something();
}
and
public #interface MyAnnotation {
boolean bool() default true;
}
That, together with final as pointed out by Jon Skeet seems to cover everything. Perhaps except the "overloaded" for keyword:
for (initializer; condition; step) and for (Type element : collection)
You can't use default as an access specifier, so I don't think even that counts. (EDIT: As Bozho pointed out, it can be used in annotations.)
final means "can't be derived from / overridden" and "is read-only" which are two different - but related - meanings.
default can be used both in a switch and as a default value in an annotation (as pointed out by Bozho)
final means "can't be derived from / overridden" and "is read-only" which are two different - but related - meanings (as pointed out by Jon)
extends can be used both to specify the supertype of a class and can be used in wildcards and type variables to put a constraint (related but not exactly the same) (List<? extends Foo>)
super can be used to specify to something in a superclass of the current class, or in a wildcard to put a constraint (List<? super Foo>)
static means both "part of the class, not an instance" (for methods, attributes or initializers) and as a static import
class to declare a class (class Foo {}), or to refer to a class literal (Foo.class) (as answered by ILMTitan)
(for can be used in a normal for loop and the "enhanced" for, but that's more like overloading (as Bozho puts it so nicely) than really having two meanings)
Something no one else has mentioned yet: the class keyword has two different uses.
Declaring a class:
class Test{};
and indicating a class literal:
Class<Test> testClass = Test.class;
The final keyword can mean different things.
When modifying classes is means that the class cannot be subclassed.
When modifying a method, it means that the method cannot be Overridden.
When modifying a variable, it means that the variable cannot point to any other variable.
The default keyword is not used as an access specifier. The absence of private, protected and public means use of default.
Example:
class Test { // default access for class.
int A; // default access for the class member.
}
Some examples of Java keywords which find different use are:
final : A final class cannot be subclassed, a final method cannot be overridden, and a final variable can occur at most once as a left-hand expression.
Super: Used to access members of a class inherited by the class in which it appears, also used to forward a call from a constructor to a constructor in the superclass.
Static: Used to create static initialization blocks, also static members and static imports.
for:Used for the conventional for loop and the newer Java 1.5 enhanced for loop.
The static keyword associates methods and fields with a class instead of instances of that class, but it's also used to signify static initialization sections as in:
public class MyClass
{
private static int a;
static
{
a = 1;
}
public static void doSomethingCool()
{
...
}
}
Pascal's comment reminded me of static imports:
import static MyClass.doSomethingCool;
public class MyOtherClass
{
public void foo()
{
// Use the static method from MyClass
doSomethingCool();
}
}
I gave a look at java keywords but it seems that keywords are unique.. you can check yourself.
By the way default can't used as an access specifier, it's inherited when noone is specified.
Do we really use default as an access specifier? No specifier at all is "default". But you don't use the keyword that way.
final has different uses:
in a variable declaration it means a variable can't be changed.
In a method signature it means a method can't be overridden
In a parameter list it means a variable can't be altered in a method.
The "extends" keyword can be for single inheritance (either implementation or "pure abstract class" aka "interface inheritance" in Java).
The "extends" keyword can also be used for multiple (interface) inheritance.
The ones who always argue that Java doesn't support multiple inheritance will hence have a hard time arguing that "extends" in those two cases is doing exactly the same thing.
Now I'm in the other camp: I consider that multiple interface inheritance is multiple inheritance and that implementation inheritance is just an OOP detail (that doesn't exist at the OOA/OOD level) and hence I consider that "extends" is really doing the same thing in both case and that hence my answer doesn't answer the question :)
But it's an interesting keyword nonetheless :)
You can think of the following things
Default
final
super
":" (colon) used at different places , which has a different meaning at different places
As all the other answers have stated, there are many keywords that server multiple purposes depending on context. I just wanted to add that there is a reason for this: There is a strong aversion to adding keywords because such additions break existing code, so when new features are added existing keywords are used if they make a reasonable fit, such as super and extends for generics and default for annotations, or they are just skipped as in the colon used in the enhanced for loop.
So my point is to expect that as the language continues to evolve even more uses are found for existing keywords rather than introducing new ones.
BTW there is no such thing as an access specifier in Java. The term in the JLS is 'access modifier'.
I wonder if there's a way to define a class in such a way that instances of it will never be members of another class (only local variables), or the other way round - only members but never local.
Is there any way in which a class can dictate the scope of it's prospective instances?
I don't think so. But I have no definitive proof.
To limit the scope you'd some sort of class annotation or class modifier and the virtual machine needed the functionality to check, whether a class (or any subclass of this restricted class) was assigned to a member or local variable and violated the constraint.
Just imagine, you had a class with the - just invented - 'onlylocal' modifier, indicating that you only allow instances in local variables.
public onlylocal class LocalUseOnlyClass implements Serializable {
//...
}
and in another class someone just did in a constructor:
private Object member;
public MyOtherClass(Serializable something) {
this.member = something
}
The Compiler couldn't detect, if you passed an instance of LocalUseOnlyClass to that constructor, so the JVM had to check and throw an exception or an error.
BTW & OT: what's your intention? - maybe there's an alternative to fulfill your underlying requirement.
no. member and local variable can be assigned to each other.
Imagine a Java class which has most features that you can find in a class. For example: it inherits from another class, implements a couple of interfaces, includes some 'static final' constants, some final constants, some static variables, instance variables, a static block, an unnamed code block (just code in {}), constructors, methods etc.
When the class in question is loaded into the JVM for the first time, in what order are the various portions of the class initialized or loaded into the JVM? What does the call stack in the JVM look like for the loading? Assume that only one classloader is at work here.
This is going back to the absolute basics/internals of Java, but I havent been able to find a good article explaining the correct sequence.
This could be described in the section 2.17.4 of the JVMS 5.0/6
2.17.4 Initialization
Initialization of a class consists of:
executing its static initializers (§2.11) and
the initializers for static fields (§2.9.2) declared in the class.
Initialization of an interface consists of executing the initializers for fields declared in the interface (§2.13.3.1).
Before a class or interface is initialized, its direct superclass must be initialized, but interfaces implemented by the class need not be initialized. Similarly, the superinterfaces of an interface need not be initialized before the interface is initialized.
A class or interface type T will be initialized immediately before one of the following occurs:
T is a class and an instance of T is created.
T is a class and a static method of T is invoked.
A nonconstant static field of T is used or assigned. A constant field is one that is (explicitly or implicitly) both final and static, and that is initialized with the value of a compile-time constant expression. A reference to such a field must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization.
Invocation of certain methods in library classes (§3.12) also causes class or interface initialization. See the Java 2 platform's class library specifications (for example, class Class and package java.lang.reflect) for details.
The intent here is that a type have a set of initializers that put it in a consistent state and that this state be 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. This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.
Before a class or interface is initialized its superclass is initialized, if it has not previously been initialized.
The updated version of Initialization in JVMS 8 is in Chapter 5.5
Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).
A class or interface may be initialized only as a result of:
The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references the class or interface (§new, §getstatic, §putstatic, §invokestatic).
All of these instructions reference a class directly or indirectly through either a field reference or a method reference.
Upon execution of a new instruction, the referenced class or interface is initialized if it has not been initialized already.
Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.
The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), 6 (REF_invokeStatic), or 8 (REF_newInvokeSpecial).
Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.
The initialization of one of its subclasses.
Its designation as the initial class at Java Virtual Machine start-up (§5.2).
Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.
Because the Java Virtual Machine is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time.
There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface.
The implementation of the Java Virtual Machine is responsible for taking care of synchronization and recursive initialization by using the following procedure.
It assumes that the Class object has already been verified and prepared, and that the Class object contains state that indicates one of four situations:
This Class object is verified and prepared but not initialized.
This Class object is being initialized by some particular thread.
This Class object is fully initialized and ready for use.
This Class object is in an erroneous state, perhaps because initialization was attempted and failed.
How about the JLS, specifically section 12.4?