I can add abstract keyword inside static initialization block, but I can't add abstract method as
abstract void draw();
So I can only add abstract class inside static block, as follows:
static {
abstract class Abstract {
abstract String test();
}
class Extends extends Abstract {
@Override
String test() {
return null;
}
}
new Extends().test();
But it doesn't sound realistic to add classes hierarchy inside static block which will be in lower access level than private, is there other usage of abstract
inside a static block?
TL;DR There's no sane usage for this feature. If I were to see this in a code review, I'd force the author to refactor it.
Sometimes, the Java spec allows you to write things that you shouldn't do in sane production code, and to me, this is one example.
Let's try to deduce a code snippet that makes use of this feature.
We're allowed to use the abstract
keyword in a static initialization block. This can only be done when defining a class, by declaring the class itself abstract
, and optionally some of its methods.
This class isn't visible outside the initialization block, so we can deduce that we'll use it inside. abstract
is all about creating instances or defining instance methods. So, it's useful only if we plan to create instances of the abstract class.
Now, the class is abstract, so to be able to create instances, we need at least one subclass.
If we have just one subclass, why would we split its funcionality into an abstract parent and one child class? That would be unneccessarily complicated, so we can assume we have multiple child classes.
So, to make any (at least half-sane) use of the abstract
keyword inside a static initialization block, this block must define one abstract parent class, multiple child classes, plus code that creates instances of these classes, like this minimum example:
static private int value;
static {
abstract class Abstract {
abstract int method1();
}
class Child1 extends Abstract {
int method1() {
return 1;
}
}
class Child2 extends Abstract {
int method1() {
return 2;
}
}
Abstract instance1 = new Child1();
Abstract instance2 = new Child2();
value = instance1.method1() + instance2.method1();
}
IMHO, using a static initializer at all should be the exception, and such a monster cries for refactoring, e.g. moving the classes out of the initialization block to become normal nested classes, or even better, moving them into their own files.
The only aspect of this abstract-in-initializer pattern different from the refactored versions is the class visibility. You get a visibility limited to only inside the static { ... }
block. But if your class is so complex and long that you fear mis-use outside of your static { ... }
block, you have lost anyway...