How to Make Anonymous Inner Classes in Java Static

Is it possible to make anonymous inner classes in Java static?

No, you can't, and no, the compiler can't figure it out. This is why FindBugs always suggests changing anonymous inner classes to named static nested classes if they don't use their implicit this reference.

Edit: Tom Hawtin - tackline says that if the anonymous class is created in a static context (e.g. in the main method), the anonymous class is in fact static. But the JLS disagrees:

An anonymous class is never abstract (§8.1.1.1). An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1). An anonymous class is always implicitly final (§8.1.1.2).

Roedy Green's Java Glossary says that the fact that anonymous classes are allowed in a static context is implementation-dependent:

If you want to baffle those maintaining your code, wags have discovered javac.exe will permit anonymous classes inside static init code and static methods, even though the language spec says than anonymous classes are never static. These anonymous classes, of course, have no access to the instance fields of the object. I don’t recommend doing this. The feature could be pulled at any time.

Edit 2: The JLS actually covers static contexts more explicitly in §15.9.2:

Let C be the class being instantiated, and let i be the instance being created. If C is an inner class then i may have an immediately enclosing instance. The immediately enclosing instance of i (§8.1.3) is determined as follows.

  • If C is an anonymous class, then:

    • If the class instance creation expression occurs in a static context (§8.1.3), then i has no immediately enclosing instance.
    • Otherwise, the immediately enclosing instance of i is this.

So an anonymous class in a static context is roughly equivalent to a static nested class in that it does not keep a reference to the enclosing class, even though it's technically not a static class.

Make anonymous class static - through static method

You can extract the Runnable to a member variable if you really think it is a performance bottleneck.

private Context context;
private TextView possesionTextView;
private int iCount;

private final Runnable r = new Runnable() {
@Override
public void run() {
int poss = -1 + Integer.parseInt(possesionTextView.getText().toString());
possesionTextView.setText(String.valueOf(poss));
iCount++;
}
};

public void cntDownPossesion() {
((Activity) context).runOnUiThread(r);
}

Java inner class and static nested class

From the Java Tutorial:

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

Static nested classes are accessed using the enclosing class name:

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:

class OuterClass {
...
class InnerClass {
...
}
}

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.

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 outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

see: Java Tutorial - Nested Classes

For completeness note that there is also such a thing as an inner class without an enclosing instance:

class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}

Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.

Why does Java create anonymous class internally as static?

The code as shown creates an anonymous class in a static context. An inner class (or non-static nested class) needs to have a reference to the enclosing object(*). In this case there is no enclosing object because it is created in a static method, so using a static nested class is the only valid option.

This can easily be demonstrated by transforming your example to

public class TestInner {
public static void main(String args[]){
Person p = new Testperson();
p.eat();
}

public class Testperson extends Person {
void eat() {
System.out.println("nice fruits");
}
}
}

Compiling this will yield the error

non-static variable this cannot be referenced from a static context

While it will compile just fine if you change it to:

public class TestInner {
public static void main(String args[]){
Person p = new Testperson();
p.eat();
}

public static class Testperson extends Person {
void eat() {
System.out.println("nice fruits");
}
}
}

*: The compiler will modify the constructor(s) of an inner class to accept the enclosing object as a parameter, and constructor calls will be rewritten to pass this as the value of that parameter. This is not the case for static nested classes.

Can we create an anonymous inner class from a concrete class?

The concept of anonymous classes (cf. JLS, §15.9.5) is simply not related/restricted to abstract classes.

new ListCell<>() {} creates an instance of a subclass (with a synthetic name) of ListCell. Subclassing is possible unless the parent class is final. Subclasses can override methods from the parent class unless they're final.

Java Anonymous Inner Class Calling Static Method

Instead of

    public void handleEvent(Event evt) {
System.err.println("starting");
Y.externalMethod();
System.err.println("finished");
}

you might have better luck with:

    public void handleEvent(Event evt) {
System.err.println("starting handleEvent");
try {
Y.externalMethod();
} finally {
System.err.println("finished handleEvent");
}
}

That is,

  1. Put the method exit trace in finally
  2. Add method names to trace lines


Related Topics



Leave a reply



Submit