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 neverstatic
(§8.1.1, §8.5.1). An anonymous class is always implicitlyfinal
(§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 insidestatic
init code andstatic
methods, even though the language spec says than anonymous classes are neverstatic
. 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,
- Put the method exit trace in
finally
- Add method names to trace lines
Related Topics
How to Read Input Character-By-Character in Java
Filtering Database Rows with Spring-Data-JPA and Spring-Mvc
How Could I Add a Simple Delay in a Java Swing Application
Implement Converters for Entities with Java Generics
How Does Java's Preparedstatement Work
Consider Defining a Bean of Type 'Package' in Your Configuration [Spring-Boot]
Which Is the Best Alternative for Java Serialization
Apache PDFbox: Problems with Encoding
Why Does the "Protected" Modifier in Java Allow Access to Other Classes in Same Package
How to Change the Arrow Style in a Jcombobox
Log4J: How to Use Socketappender
How to Tune Tomcat 5.5 Jvm Memory Settings Without Using the Configuration Program
How to Set Classpath When I Use Javax.Tools.Javacompiler Compile the Source
Programmatically Change Log Level in Log4J2
Do Any Jvm's Jit Compilers Generate Code That Uses Vectorized Floating Point Instructions