I know it depends on the context in which the anonymous class has been written (static or non static method).
but look this part of code:
public class A {
int fieldOfA;
private static class B {
int fieldOfB;
}
public static void main(String[] args) {
B obj = new B() { //this anonymous class is static becuase is in the main method.
private static void testMethod() { //so why here i have an error and i can put just a non-static method
//if my class is static ?
//a class static can have static method, but this class no, why?
}
};
}
}
it's sure that anonymous class are static?
An anonymous class is static if the context is static. e.g. in a static method.
An anonymous class is non static if there is a non static context, whether you need it to be non-static or not. The compiler is not smart enough to make a class static if the non static context is not used.
In this example, two anonymous classes were created. One in a static method has no reference to an outer class and is like a static nested class.
Note: these classes are still called "Inner" and cannot have static members even though they have no reference to an Outer class.
import java.util.Arrays;
public class Main {
Object o = new Object() {
{
Object m = Main.this; // o has a reference to an outer class.
}
};
static Object O = new Object() {
// no reference to Main.this;
// doesn't compile if you use Math.this
};
public void nonStaticMethod() {
Object o = new Object() {
{
Object m = Main.this; // o has a reference to an outer class.
}
};
printFields("Anonymous class in nonStaticMethod", o);
}
public static void staticMethod() {
Object o = new Object() {
// no reference to Main.this;
// doesn't compile if you use Math.this
};
printFields("Anonymous class in staticMethod", o);
}
private static void printFields(String s, Object o) {
System.out.println(s + " has fields " + Arrays.toString(o.getClass().getDeclaredFields()));
}
public static void main(String... ignored) {
printFields("Non static field ", new Main().o);
printFields("static field ", Main.O);
new Main().nonStaticMethod();
Main.staticMethod();
}
}
prints
Non static field has fields [final Main Main$1.this$0]
static field has fields []
Anonymous class in nonStaticMethod has fields [final Main Main$3.this$0]
Anonymous class in staticMethod has fields []
From JLS 15.9.5:
An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1).
Section 8.1.3 talks more about inner classes, including when they occur in a static context. But they're never static themselves, and thus can't declare static members (other than constant variables).
Related
As per java doc, static block is executed when the class is initialized.
Could anyone please tell me why static block is not executed when I run below code?
class A {
static {
System.out.println("Static Block");
}
}
public class Main {
public static void example1() {
Class<?> class1 = A.class;
System.out.println(class1);
}
public static void example2() {
try {
Class<?> class1 = Class.forName("ClassLoading_Interview_Example.ex1.A");
System.out.println(class1);
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
example1();
}
}
A class's static initialization normally happens immediately before
the first time one of the following events occur:
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 [...]
You are currently not doing any of the above.
So, by replacing
Class<?> class1 = A.class;
System.out.println(class1);
with this for example
A object = new A();
will give you your result.
Referencing A.class will not resulting in executing A's static initializers, see here
Initialization of a class consists of executing its static
initializers and the initializers for static fields (class variables)
declared in the class.
And
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.
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 field is not a constant
variable (§4.12.4).
This question already has answers here:
non-static variable this cannot be referenced from a static context when creating instance of class
(2 answers)
Closed 5 years ago.
Wondering - why there is such error message during compile:
ClassHierarchyTest1.this Cannot be referenced from a static context
Source code:
public class ClassHierarchyTest1 {
class Foo {
int a;
Foo(int b) {
this.a = b;
}
}
public static void main(String[] args) {
Foo f = new Foo(1); // this line has the error message
}
}
Foo is an inner class and therefore you can access it only through instance of ClassHierarchyTest1. Like that:
Foo f = new ClassHierarchyTest1().new Foo(1);
Another option is to define foo as static:
static class Foo{...}
Foo is a member of ClassHierarchyTest1 . Hence you have to use ClassHierarchyTest1 inorder to access it's members.
Docs of Inner Classes
An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.
class OuterClass {
...
class InnerClass {
...
}
}
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Not at all strange.
Your inner class itself is not static. Thus it always needs an object of the outer enclosing class. Which you don't have in your static main.
So you have to change Foo to be static (of course you then can't use the "outer this"), or you have to create an instance of your outer class first,and call new on that object.
add static to your class
public class ClassHierarchyTest1 {
class static Foo {
int a;
Foo(int b) {
this.a = b;
}
}
public static void main(String[] args) {
Foo f = new Foo(1); // this line has the error message
}
}
For example I've got simple class
class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + obj.i);
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
Why I can get access to i in static method?
private members can be accessible with in the class. Your static method belongs to the same class. Hence you can access.
Modifier Class Package Subclass World
---------------------------------------------
private **Y** N N N
Update: To avoid the confusion, move the static method to other class and try once.
Don't get confused with static and private/public/[default]. Those are two separate things. A static function can access private non-static field because it is part of the class. And thats whats private does, only restricting access to the class level, without any distinction being made between static or not.
If it's the staticness that's bothering you, obj is a proper "not static" object, which us why it has an accessible non-static field. The method being static is irrelevant.
you are accessing instance of object not directly class variable. when you use direly "i" without reference to object its not allowed.
Private variable visibility is by default in with in class access .
public class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + i); //compile Error ::Cannot make a static reference to the non-static field i
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
I'm unsure what this does, I haven't seen it before and can't find any information about it.
private static String[] names = { "A.ttf" };
private static Map<String, Font> cache = new ConcurrentHashMap<String, Font>(names.length);
static {
for (String name : names) {
cache.put(name, getFont(name));
}
}
That is not a static method but a static block.
Static blocks are executed first(in same order they are declared) when class gets loaded and usually used for initializing things.
in your case it puts all names in "names" to cache.
refer this or an answer on SO for more info
A block is denoted by {\\some code}. A placed static keyword denotes that it is a static block. static block is known as Static Initializers and non static block is known as Instance Initializers.
None of them can contain return statement.
The non-static block will be called every time you are creating a new instance and it will be called/executed just before the Constructor. The static block will be called/executed only once and it will be the first time your are accessing the class.
Example:
class A {
static{ // static
System.out.println("Static block of Class A");
}
{ // non-static
System.out.println("Non-Static block of a instance of Class A");
}
public A(){
System.out.println("Constructing object of type A");
}
}
public class StaticTest {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
Output:
static block of Class A
Non-Static block of a instance of Class A
Constructing object of type A
Non-Static block of a instance of Class A
Constructing object of type A
As a rule in object-oriented paradigm, a static method can have access only to static variables and static methods. If it is so, an obvious question arises as to how can the main() method in Java has access to non-static members (variables or methods) even though it is specifically public static void...!!!
The main method does not have access to non-static members either.
public class Snippet
{
private String instanceVariable;
private static String staticVariable;
public String instanceMethod()
{
return "instance";
}
public static String staticMethod()
{
return "static";
}
public static void main(String[] args)
{
System.out.println(staticVariable); // ok
System.out.println(Snippet.staticMethod()); // ok
System.out.println(new Snippet().instanceMethod()); // ok
System.out.println(new Snippet().instanceVariable); // ok
System.out.println(Snippet.instanceMethod()); // wrong
System.out.println(instanceVariable); // wrong
}
}
By creating an object of that class.
public class Test {
int x;
public static void main(String[] args) {
Test t = new Test();
t.x = 5;
}
}
The main() method cannot have access to the non-static variables and methods, you will get “non-static method cannot be referenced from a static context” when you try to do so.
This is because by default when you call/access a method or variable it is really accessing the this.method() or this.variable. But in the main() method or any other static method(), no "this" objects has yet been created.
In this sense, the static method is not a part of the object instance of the class that contains it. This is the idea behind utility classes.
To call any non-static method or variable in a static context, you need to first construct the object with a constructor or a factory like your would anywhere outside of the class.
YourClass inst = new YourClass();
inst.nonStaticMethod();
inst.nonStaticField = 5;
You have to instantiate the object you wish to access.
For example
public class MyClass{
private String myData = "data";
public String getData(){
return myData;
}
public static void main(String[] args){
MyClass obj = new MyClass();
System.out.println(obj.getData());
}
}
Through the reference to the object.
public class A {
private String field;
public static void main(String... args) {
//System.out.println(field); <-- can not do this
A a = new A();
System.out.println(a.field); //<-- access instance var field that belongs to the instance a
}
}
You must create an instance of the class in order to reference instance variables & methods.