Java: When is the variable "this" initialized? - java

public class MainMDI extends javax.swing.JFrame {
private static MainMDI thiz;
public MainMDI() {
initComponents();
thiz = this;
}
}
I'm creating an MDI application in swing. Class MainMDI is the main class of the application and therefore the main method resides in that class. The above code creates a static variable called thiz that points to the instance of class MainMDI when the application runs.
I'm planning to use variable thiz to access non-static (instance) members of class MainMDI from within the main method.(I cannot access non-static members from from within the main method since the main method is a static member in class MainMDI in my application).
public class MainMDI extends javax.swing.JFrame {
private static MainMDI thiz = this;
public MainMDI() {
initComponents();
}
}
But when I attempt to initialize variable thiz as in the above code, compiler says non-static variable this cannot be referenced from a static context. But I'm not referring to this in a static context here am I? Is this because variable this, being non-static, is not yet initialized when the static variable this is initialized?
Also, would it have been a better programming practice if I had not set class MainMDI as the main class and created another class with a main method in it and set that class as the main class?

But when I attempt to initialize variable thiz as in the above code,
compiler says non-static variable this cannot be referenced from a
static context. But I'm not referring to this in a static context here
am I?
Yes, you are. Static class variables are initialized when the class is loaded (not when an object instance is being created). There is no this in that context. The code:
private static javax.swing.JFrame thiz = this;
Will simply not work. Despite your assertions to the contrary, you do want a singleton. Otherwise, given N possible object instances of your MainMDI object, which one would you be expecting to access from a static context? You should consider refactoring your code rather than trying to strong-arm around Java language semantics.

this means "the object instance currently being operated on", it only makes sense inside a non-static member function. In general this is implicitly passes to each non-static member function when you call that member function so it'd be fair to say that it is initialized right before a non-static member function gets called.
Whether factoring out a class with "main" method is a good idea will heavily depend on actual implementation details.

Related

When do we use Class Variable, rather than using Object of class?

I am studying about static variables. They say that static variables are class variables.
They gave an example like this
class Bicycle{
private static int noOfBicycles = 0;
}
When calling this we can directly use the name of the class to call this variable without creating any object, i.e.
Bicycle.noOfBicycles
So when do we need these static variables rather than instance variables?
When a variable is declared as static, a single copy of the variable is created and shared among all objects at a class level. Static variables are, essentially, global variables. All instances of the class share the same static variable.
Instance variables are non-static variables and are declared in a class outside any method, constructor or block. As instance variables are declared in a class, these variables are created when an object of the class is created and destroyed when the object is destroyed.
The main differences between static and non static variables are
better explained here
Also already answered Static vs Instance Variables: Difference?

Use of this and super within local classes defined in a static context

I was going through the following code while studying Java local classes :-
class A {
protected int one;
}
class Outer {
static void staticMethod(){
class InnerLocal extends A {
double first = this.one;
double second = super.one;
}
}
}
My doubt is that when we declare the local classes inner to static method or static initializer block then they implicitly work as static member classes as they need no outer class to instantiate them. However I know the difference clearly between a static member class and static local class(i.e. the inner class defined in static block), the problem is that Java does not allows the object references 'this' and 'super' to be used in static context but the code above compiles perfectly.
Can anyone please provide me the reason why Java compiler doesn't complains on using 'this' and 'super' in static context in the above case? Thanks!:)
My doubt is that when we declare the local classes inner to static method or static initializer block then they implicitly work as static member classes as they need no outer class to instantiate them
This is the root cause of your confusion. Just because a method is static does not mean that anything declared within the method is also static. If you declare a variable (say int a) inside a static method, it is said to be a local variable. It would make no sense to say that a is a method local static variable. Similarly, it would make no sense to say that InnerLocal is a method local static class. (There is no such thing as static local variable in Java)
InnerLocal is therefore a regular class that extends from A and inherits the a member variable from A and is able to access it either through this or through super. It would also help to know that final is the only non-access modifier that can be used within a method in Java.
Java does not allows the object references this and super to be used in static context but the code above compiles perfectly.
static as in "static class" is not the same as static as in "static context".
All instance methods and constructors have access to this and super. Since constructors have access to this and super, initializers of instance fields have access to this and super as well. A static inner class has no outer instance, but it has its own instance. That is what this refers to.
In contrast, static methods have no access to this and super, regardless of the class in which these static methods are defined (top-level, static inner, non-static inner, anonymous, etc.)

Does a class gets loaded in memory when a static variable is accessed in java?

I have a class:
public class Foo {
public static boolean flag = false;
//some code
}
I am using this boolean flag in another class:
public class FooImpl{
public static void main (String args[]) {
if (Foo.flag){
//Line 1
//some code
}
}
}
So at Line 1, does class Foo gets fully loaded in the memory or just the static variable gets loaded with default value?
A classes static initialization normally happens immediately before the first time one of the following events occurs:
an instance of the class is created,
a static method of the class is invoked,
a static field of the class is assigned,
a non-constant static field is used, or
See JLS 12.4.1.
The class gets loaded when there is a static reference to the class. It is loaded by ClassLoader [java.lang.ClassLoader].
when you access a class member or constructor [creating an instance of that class] you need information about the class and it gets loaded.
you might have seen some ClassNotFoundException for some library function calls. The ClassLoader is behind that.
But there is other fact that the class gets initialized when something in the class is used first.
Initialization of a class consists of executing its static initializers and the initializers
for static fields (class variables) declared in the class.
In line 1 you are referring to a member of class and its loaded for sure.
Initialization Occurs:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable
T is a top level class, and an assert statement lexically nested within T is executed.
A reference to a static field (ยง8.3.1.1) causes initialization of only the class or
interface that actually declares it, even though it might be referred to through the
name of a subclass, a subinterface, or a class that implements an interface.

Accessing class in static java method

We have self registering subclasses of 'Handler' which we want to access through Subclass.me(). Is something similar to this possible in Java: ?
public class Handler{
static Vector<Handler> register=new Vector<Handler>();
public static Handler me() {
return register.get( this.class);// TODO
}
}
public class SubClass extends Handler{
SubClass(){register.add(this);}// OK
}
To clarify the question: Is it possible to retrieve the CLASS when calling a static java method? this.class obviously doesn't work, because 'this' is not available.
Static methods belong to the class. They cannot be overridden.
MyClass.myStaticMethod()
is the only correct way of accessing a static method.
In java, you cannot make a static reference to the non-static method/variable. So,
If you want to access a non-static method / variable then you must
create an instance of the class first.
If you are going to access a static method / variable then you can
access it directly through the class name without creating a
instance.
Because, the static method and variable are belong to the Class not to the Instance while the non-static method and variable are belong to the Instance not to the Class.

java objects, shared variables

I have a simple question here.
If I declare a variable inside an object which was made [declared] in the main class, like this:
public static int number;
(
usually I declare it like this :
private int number;
)
can it be used in a different object which was also made [declared] in the main class?
btw I do not care about security atm, I just want to make something work, don't care about protection)
Here's a telling quote from Java Language Specification:
JLS 8.3.1.1 static Fields
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.
[Example program follows...]
In short, a static field is a class variable: it belongs to the class, as opposed to the instances of the class. In a way, you can think of a static field as a variable shared by instances of the class, but it's much more consistent to think of static fields as belonging to the class, just like static method also belongs to the class, etc.
Since they belong to the class, they do not require an instance of said class to access (assuming adequate visibility), and in fact it's considered bad programming practice to access static members through an instance instead of a type expression.
Related questions
Java - static methods best practices
Static methods
calling non-static method in static method in Java
non-static variable cannot be referenced from a static context (java)
When NOT to use the static keyword in Java?
Static variables and methods
If the class holding 'number' is called MyClass
you can refer to it as MyClass.number from any method.
Doing so for a variable is not good design though.
There are really two issues here: public vs. private in the context of inner classes, and static variables.
Part 1:
static means that you don't need an instance of the class to access that variable. Suppose you have some code like:
class MyClass {
public static String message = "Hello, World!";
}
You can access the property this way:
System.out.println(MyClass.message);
If you remove the static keyword, you would instead do:
System.out.println(new MyClass().message);
You are accessing the property in the context of an instance, which is a copy of the class created by the new keyword.
Part 2:
If you define two classes in the same java file, one of them must be an inner class. An inner class can have a static keyword, just like a property. If static, it can be used separately. If not-static, it can only be used in the context of a class instance.
Ex:
class MyClass {
public static class InnerClass {
}
}
Then you can do:
new MyClass.InnerClass();
Without the 'static', you would need:
new MyClass().new InnerClass(); //I think
If an inner class is static, it can only access static properties from the outer class. If the inner class is non-static, it can access any property. An inner class doesn't respect the rules of public, protected, or private. So the following is legal:
class MyClass {
private String message;
private class InnerClass {
public InnerClass() {
System.out.println(message);
}
}
}
If the inner class has keyword static, this would not work, since message is not static.
static variables are shared by all instances of a given class. If it's public, it is visible to everything.
non-static variables belong to only one instance.
Since your main method is static, it can only see static variables. But you should avoid working statically - make an instance of a class, and pass the data around as method/constructor parameters, rather than sharing it via static variables.

Categories

Resources