Not actually global variables, but just variables that are class-wide.
For example, I have this initialization:
MyObj obj = new MyObj();
And then I have this method:
public void Foo(){
obj.doSomething;
}
Let's say that I'm not able to use a constructor(this is pertaining to android). Will the variable be guaranteed to always be initialized before any methods in the class is called?
(To be clear: 1) Java doesn't have global variables. 2) Java has class (i.e. static) fields and instance fields, as well as local variables. 3) The example appears to show an instance field, so I am assuming that is what you are asking about.)
Are java global variables guaranteed to initialize first?
Yes. Except in pathological cases that I will explain below.
When an object is created, the following things are done in the following order:
The object is allocated on the heap with the correct object type, and all instance fields are "default initialized" to zero, false or null.
The expressions in the super(...) or this(...) are evaluated and the constructor for the next class up the chain is called. (This recurses up the chain constructor, so that the Object constructor gets executed first.)
The instance variable initializers and any instance initializer blocks are executed in order.
The body of the constructor is executed.
The constructor returns.
All of this happens when you execute new SomeClass(...).
So, in your example (as written), you can sure that the instance variable obj will be initialized before your method is called.
Now for the pathological cases. Consider this:
public class Foo {
private int a = someMethod();
private int b = 42;
public Foo() {
}
private int someMethod() {
return this.b;
}
}
In this case, the initializer for a will call someMethod before b has been initialized, and hence someMethod will return the default initial value of b ... zero. You could also "implement" the pathological example using an instance initialize block. However, if you called someMethod within the Foo constructor, you can be sure that the instance variable's initializer will have been executed.
Indeed there are other pathological cases to consider. If the implementation of someMethod in the above were to call a method in another class, passing this as an argument, then the other class could call methods on the partially initialized Foo instance. (This is called unsafe publication. It is particularly insidious if the partially initialized instance can be accessed by another thread, because that invalidates various Java memory model guarantees.)
Will the variable be guaranteed to always be initialized before any methods in the class is called?
Yes. You are correct. It's already initialized since it's declared even on top of constructor and ready for the use later.
And it's up to you, where you are going to use that instance member, weather in constructor or in methods later, but it's guaranteed to initialize before the constructor called.
First of all, it's not a global variable. It's an instance variable. It is guaranteed to be initialized before the constructor is called, so it is guaranteed to be initialized when Foo is called.
That is what Myobj() is. It is a default constructor and it gets overridden if you explicitly define a constructor in your class.
All variables gets its memory as soon as You make its Object (Reference Variable) and class get its space as soon as the new keyword gets compiled even before your statement MyObj obj = new MyObj(); gets compiled.
Related
I would appreciate help in understanding the following from 'Java Concurrency in Practice':
Calling an overrideable instance method(one that is neither
private nor final) from the constructor can also allow the
this reference to escape.
Does 'escape' here simply mean that we may probably be calling an instance method,before the instance is fully constructed?
I do not see 'this' escaping the scope of the instance in any other way.
How does 'final' prevent this from happening?Is there some aspect of 'final' in instance creation that I am missing?
It means calling code outside the class, and passing this.
That code will assume that the instance is fully initialized, and may break if it isn't.
Similarly, your class might assume that some methods will only be called after the instance is fully initialized, but the external code is likely to break those assumptions.
final methods cannot be overridden, so you can trust them to not pass this around.
If you call any non-final method in the constructor for a non-final class, a derived class might override that method and pass this anywhere.
Even when you call final methods, you still need to make sure that they are safely written – that they do not pass this anywhere, and that themselves don't call any non-final methods.
"Escape" means that a reference to the partially-constructed this object might be passed to some other object in the system. Consider this scenario:
public Foo {
public Foo() {
setup();
}
protected void setup() {
// do stuff
}
}
public Bar extends Foo implements SomeListener {
#Override protected void setup() {
otherObject.addListener(this);
}
}
The problem is that the new Bar object is being registered with otherObject before its construction is completed. Now if otherObject starts calling methods on barObject, fields might not have been initialized, or barObject might otherwise be in an inconsistent state. A reference to the barObject (this to itself) has "escaped" into the rest of the system before it's ready.
Instead, if the setup() method is final on Foo, the Bar class can't put code in there that will make the object visible before the Foo constructor finishes.
I believe the example is something like
public class Foo {
public Foo() {
doSomething();
}
public void doSomething() {
System.out.println("do something acceptable");
}
}
public class Bar extends Foo {
public void doSomething() {
System.out.println("yolo");
Zoom zoom = new Zoom(this); // at this point 'this' might not be fully initialized
}
}
Because the super constructor is always called first (either implicitly or explicitly), the doSomething will always get called for a child class. Because the above method is neither final nor private, you can override it in a child class and do whatever you want, which may conflict with what Foo#doSomething() was meant to do.
Per secure coding
Example BAD code:
final class Publisher {
public static volatile Publisher published;
int num;
Publisher(int number) {
published = this;
// Initialization
this.num = number;
// ...
}
}
If an object's initialization (and consequently, its construction) depends on a security check within the constructor, the security check can be bypassed when an untrusted caller obtains the partially initialized instance. See rule OBJ11-J. Be wary of letting constructors throw exceptions for more information.
final class Publisher {
public static Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
Because the field is nonvolatile and nonfinal, the statements within
the constructor can be reordered by the compiler in such a way that
the this reference is published before the initialization statements
have executed.
Correct code:
final class Publisher {
static volatile Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
The this reference is said to have escaped when it is made available
beyond its current scope. Following are common ways by which the this
reference can escape:
Returning this from a non-private, overridable method that is invoked from the constructor of a class whose object is being
constructed. (For more information, see rule MET05-J. Ensure that
constructors do not call overridable methods.)
Returning this from a nonprivate method of a mutable class, which allows the caller to manipulate the object's state indirectly. This
commonly occurs in method-chaining implementations; see rule VNA04-J.
Ensure that calls to chained methods are atomic for more information.
Passing this as an argument to an alien method invoked from the constructor of a class whose object is being constructed.
Using inner classes. An inner class implicitly holds a reference to the instance of its outer class unless the inner class is declared
static.
Publishing by assigning this to a public static variable from the constructor of a class whose object is being constructed.
Throwing an exception from a constructor. Doing so may cause code to be vulnerable to a finalizer attack; see rule OBJ11-J. Be wary of
letting constructors throw exceptions for more information.
Passing internal object state to an alien method. This enables the method to retrieve the this reference of the internal member object.
This rule describes the potential consequences of allowing the this
reference to escape during object construction, including race
conditions and improper initialization. For example, declaring a field
final ordinarily ensures that all threads see the field in a fully
initialized state; however, allowing the this reference to escape
during object construction can expose the field to other threads in an
uninitialized or partially initialized state. Rule TSM03-J. Do not
publish partially initialized objects, which describes the guarantees
provided by various mechanisms for safe publication, relies on
conformance to this rule. Consequently, programs must not allow the
this reference to escape during object construction.
In general, it is important to detect cases in which the this
reference can leak out beyond the scope of the current context. In
particular, public variables and methods should be carefully
scrutinized.
Let's look at the following code snippet in Java.
package trickyjava;
class A
{
public A(String s)
{
System.out.println(s);
}
}
final class B extends A
{
public B()
{
super(method()); // Calling the following method first.
}
private static String method()
{
return "method invoked";
}
}
final public class Main
{
public static void main(String[] args)
{
B b = new B();
}
}
By convention, the super() constructor in Java must be the first statement in the relevant constructor body. In the above code, we are calling the static method in the super() constructor parameter list itself super(method());.
It means that in the call to super in the constructor B(), a method is being
called BEFORE the call to super is made! This should be forbidden by the compiler but it works nice. This is somewhat equivalent to the following statements.
String s = method();
super(s);
However, it's illegal causing a compile-time error indicating that "call to super must be first statement in constructor". Why? and why it's equivalent super(method()); is valid and the compiler doesn't complain any more?
The key thing here is the static modifier. Static methods are tied to the class, instance methods (normal methods) are tied to an object (class instance). The constructor initializes an object from a class, therefore the class must already have been fully loaded. It is therefore no problem to call a static method as part of the constructor.
The sequence of events to load a class and create an object is like this:
load class
initialize static variables
create object
initialize object <-- with constructor
object is now ready for use
(simplified*)
By the time the object constructor is called, the static methods and variables are available.
Think of the class and its static members as a blueprint for the objects of that class. You can only create the objects when the blueprint is already there.
The constructor is also called the initializer. If you throw an exception from a constructor and print the stack trace, you'll notice it's called <init> in the stack frame. Instance methods can only be called after an object has been constructed. It is not possible to use an instance method as the parameter for the super(...) call in your constructor.
If you create multiple objects of the same class, steps 1 and 2 happen only once.
(*static initializers and instance initializers left out for clarity)
Yep, checking the JVM spec (though admittedly an old one):
In the instance init method, no reference to "this" (including the implicit reference of a return) may occur before a call to either another init method in the same class or an init method in the superclass has occurred.
This is really the only real restriction, so far as I can see.
The aim of requiring the super constructor to be invoked first is to ensure that the "super object" is fully initialized before it is used (It falls short of actually enforcing this because the super constructor can leak this, but that's another matter).
Calling a non-static method on this would allow the method to see uninitialized fields and is therefore forbidden. A static method can only see these fields if it is passed this as argument. Since accessing this and super is illegal in super constructor invocation expressions, and the call to super happens before the declaration of any variables that might point to this, allowing calls to static methods in super constructor invocation expressions is safe.
It is also useful, because it allows to compute the arguments to the super constructor in an arbitrarily complex manner. If calls to static methods weren't allowed, it would be impossible to use control flow statements in such a computation. Something as simple as:
class Sub extends Super {
Sub(Integer... ints) {
super(Arrays.asList(ints));
}
}
would be impossible.
This is one situation where the java syntax hides what's really going on, and C# makes it a bit clearer.
In C# your B would look like
class B : A {
public B() : base(method()) {
}
private static String method() {
return "method invoker";
}
}
Although the java syntax places super(method) within the constructor it's not really called there: All the parent initialization is run before your subclass constructor. The C# code shows this a little more clearly; by placing super(method()) at the first line of the java constructor you're simply telling java to use the parameterized constructor of the super class rather than the parameterless version; this way you can pass variables to the parent constructor and they'll be used in the initialization of the parent level fields before your child's constructor code runs.
The reason that super(method()) is valid (as the first line in a java constructor) is because method() is being loaded with the static elements--before the non-static ones, including the constructors--which allows it to be called not only before B(), but before A(String) as well. By saying
public B() {
String s = method();
super(s);
}
you're telling the java compiler to initialize the super object with the default constructor (because the call to super() isn't the first line) and you're ready to initialize the subclass, but the compiler then becomes confused when it sees that you're trying to initialize with super(String) after super() has already run.
A call to super is a must in java to allow the parent to get initalized before anything with child class starts.
In the case above, if java allows String s= method(); before the call to super, it opens up flood gate of things that can be done before a call to super. that would risk so many things, essentially that allows a half baked class to be used. Which is rightly not allowed. It would allow things like object state (some of which may belong to the parent) being modified before it was properly created.
In case of super(method()); call, we still adhere to the policy of completing parent initialization before child. and we can use a static member only, and static member of child classes are available before any child objects are created anyways. so the method is avilable and can be called.
OK..i think, this one could be relevant that, if we are calling some member with Super, then it first try to invoke in super class and if it doesn't find same one then it'll try to invoke the same in subclass.
PS: correct me if i'm wrong
Many articles say objects get created only after the class's constructor gets called. But I found this snippet and it works fine.
public class A {
public A(){
this.foo();//line #1
}
private void foo() {
System.out.print("without an instance..!!!!");
}
}
class B extends A
{
public static void main(String[] args){
A a = new A(); //line #2
}
}
Here you see, I'm trying to create an object of its super class in line #2 and in its constructor how come its method got called without an instance. What's going on here, is Constructer of instance of A is getting called here.?
The constructor is always called when an object is created. Even if you don't explicitly define a constructor, the compiler will generate one for you with an empty body.
You may call other methods of the class from the constructor. All non-static methods get an implicit (compiler generated) parameter to this, the actual class instance. However, it is important to know that while executing the constructor, the object is not yet fully created, although all data members of the class in question (if there are such) have already been initialized, at least to some default value. Because of this, you
should not publish this (i.e. pass it to other objects / threads) before exiting the constructor call, and
you should not call non-final, non-private methods from the constructor.
Doing either of these (in a non-final class) means that you give access to an object not yet fully constructed, which may result in subtle, hard to find bugs later. E.g. if the virtual method in question is overridden in a subclass and the implementation depends on some member defined and initialized only in the subclass constructor, the method gets called before the subclass member is correctly initialized, thus it won't have the value you would expect.
Because public static void main is the entry point of the programm. So you do not require to create instance of the class B.
The method signature for the main() method contains three modifiers:
* public indicates that the main() method can be called by any object.
* static indicates that the main() method is a class method.
* void indicates that the main() method has no return value.
Read more : Understanding public static void main function
So that Constructor of A is get called when the programm get executed and that it calls the foo method of the super class A.
It's not called without an instance.
You call it on this - that's an instance.
The constructor of A is getting called because you called it directly. However, if you wished to call A through B, within Main [which is called without a current instance of the containing class B (1 because its static, and 2. its reserved for the beginning of the application)] you would just change the "new A()" to "new B()"
Since you're using a constructor with no parameters, a default constructor in automatically generated at compile time.
Whether main() is the entry point or not is not the explanation. The reason is that main() is static, therefore doesn't require an instance of its class.
No instance of B is ever created by this program.
class A is public, and its inherited by class B. class B can instantiate class A, with
A object=new A()
and the object initialization is done by Constructor method defined automatically. Constructor of A in turn calls method foo(), which is private to class A. As far as i know, to call a method from a class which is in the same class scope, no instance is needed.
I have a method that uses a SwingWorker. Part of the code is shown below:
public class mySocket {
public void writePacket(final String packet) {
// schedules execution on the single thread of the executor (so only one
// background operation can happen at once)
//
executor.execute(new SwingWorker<String, Void>() {
#Override
protected String doInBackground() throws Exception {
// called on a background thread
System.out.println("writing out this packet->" + packet + "
<-");
out.println(packet);
String thePacket = readPacket();
return thePacket;
}
..................
My questions are about the signature of the writePacket method. The variable packet must be declared final or the compiler complains because SwingWorker is an inner class. This raises the following questions about how and when I can assign values to this variable:
Final to me means that the variable can only be assigned a value once. But because the declaration is part of the signature of a method, I don't know what this means in this context.
I always assumed that final variables were assigned values when the class was instantiated but here it is assigned when the method is called. Does the variable passed to the method also need to be declared final and assigned in the class's constructor for this to work?
Can I call the method more than once with different values for packet or because the variable is declared final, does this mean that if I want to call the method with different values, I need to reinstantiate the class for each new value of the variable packet ?
Thanks in advance for your help.
Elliott
1. Final to me means that the variable can only be assigned a value once. But because the declaration is part of the signature of a method, I don't know what this means in this context.
It just means that you can't reassign a new value to the variable packet.
2. I always assumed that final variables were assigned values when the class was instantiated but here it is assigned when the method is called. Does the variable passed to the method also need to be declared final and assigned in the class's constructor for this to work?
You can have local final variables as well. Same rules applies, but they are unrelated to constructor / this reference.
3. Can I call the method more than once with different values for packet or because the variable is declared final, does this mean that if I want to call the method with different values, I need to reinstantiate the class for each new value of the variable packet ?
You can call the method several times with different values. The packet variable is like a local variable. and No, you don't need to reinstantiate the class for each value / call.
Further SO reading:
Cannot refer to a non-final variable inside an inner class defined in a different method
Cannot refer/modify non-final variable in an innerclass
access to variable within inner class in java
The inner class can only reference final variables because the variable that is wantd is actually passed to the inner class ctor as a parameter. If the variable was not final, and changed after the inner class was created, it would no longer be holding onto the current but previous variable. To avoid such strangeness and to keep things simple, variables/parameters must be final for an inner class to read.
Final to me means that the variable can only be assigned a value
once. But because the declaration is part of the signature of a
method, I don't know what this means in this context.
It means the same thing, you can't re-assign the variable.
// this compiles
public void foo(String bar){
bar = "xyz";
}
// this doesn't
public void foo(final String bar){
bar = "xyz";
}
I always assumed that final variables were assigned values when
the class was instantiated but here it is assigned when the method is called.
No, local variables can also be final, and parameters too. They are assigned once per scope (block or method level).
Does the variable passed to the method also need to be
declared final and assigned in the class's constructor for this to
work?
No, that's totally irrelevant
Can I call the method more than once with different values for packet
or because the variable is declared final, does this mean that if I
want to call the method with different values, I need to reinstantiate
the class for each new value of the variable packet ?
No, see above. It's a new variable for each method call.
Final to me means that the variable can only be assigned a value once. But because the declaration is part of the signature of a method, I don't know what this means in this context.
Same thing. It means you cannot re-assign a new value to the local variable that contains the parameter (that is considered bad practice anyway).
I always assumed that final variables were assigned values when the class was instantiated but here it is assigned when the method is called
That first part is true for final instance variables, not for local variables.
But the idea is the same: They need to be assigned a value and it can happen only once.
Can I call the method more than once with different values for packet or because the variable is declared final, does this mean that if I want to call the method with different values, I need to reinstantiate the class for each new value of the variable packet ?
You can call it many times. The parameter being declared final has no impact to code calling of the method (just for its implementation).
I have noticed in the code in my system that someone instantiated an anonymous class as follows
Class ExampleClass{
MyObj obj;
methodA(new ClassA(){
#override public void innerMethodA(){
//code...
}
});
}
So far so good.
Now, in order to use obj that was declared before the method I usually define it as final.
I don't really understand why but i do because the compiler asks.
In this code i see in innerMethodA() the usage of
ExampleClass.this.obj()
without final.
My questions :
1. why do I have to put final when I use obj?
2. what is ExampleClass.this ? Notice that ExampleClass is the Class not an instance. then what is the "this"? if it has several instances?
3. What happens if I change the obj while the inner method runs (in my code inner method runs in a loop so I plan on changing it . will it explode?)
You have to use final when you capture the variable of a local variable... not an instance variable of the enclosing class.
ExampleClass.this is a reference to the instance of ExampleClass associated with the instance of the subclass of ClassA. In your case, it will be the same as this within methodA.
It won't explode - it will just change the value of obj. Think of it as capturing the value of ExampleClass.this (so you can't change that) but you can change the data within the object referred to by ExampleClass.this.
There are no "true" closures (functions that capture scope) in Java. See e.g.http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different
You can use this form to reference ambiguous methods / variables in the scope of "ExampleClass".
You cannot change the reference. What you can do is use an indirection, e.g. a final reference to an object that can swap it's values. An example would be the class of Atomic value holders, e.g. AtomicReference.
Because, the way you described it, in this case, they are not using ExampleClass.this.obj, they are calling the method ExampleClass.this.obj().
ExampleClass.this refers to the encapsulating instance of ExampleClass in which this ClassA instance is instantiated.
Not necessarily.