Java – abstract classes used in static blocks
I can add the abstract keyword in the static initialization block, but I cannot add abstract methods
abstract void draw();
Therefore, I can only add abstract classes in static blocks, as shown below:
static { abstract class Abstract { abstract String test(); } class Extends extends Abstract { @Override String test() { return null; } } new Extends().test();
However, adding a class hierarchy to a static block is not true, because the access level of a static block is lower than that of a private block. Are there other abstract uses in a static block?
Solution
TL; Dr there is no reasonable use of this function If I see this in the code review, I will force the author to refactor it
Sometimes, the Java specification allows you to write operations that you shouldn't perform in rational production code. For me, this is an example
Let's try to infer the code snippet that uses this function
We are allowed to use the abstract keyword in static initialization blocks This can only be done by declaring that the class itself is abstract and some optional methods when defining the class
This class is invisible outside the initialization block, so we can infer that we will use it internally Abstract is about creating instances or defining instance methods Therefore, it is only useful when we plan to create instances of abstract classes
Now, the class is abstract, so in order to create instances, we need at least one subclass
If we have only one subclass, why do we divide its functions into abstract parent and subclass? This will be unnecessarily complex, so we can assume that we have multiple subclasses
Therefore, to use the abstract keyword (at least semi rational) in a static initialization block, this block must define an abstract parent class, multiple subclasses, and the code to create instances of these classes, as shown in the following 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(); }
With all due respect, the use of static initializers should be an exception, and such monsters call for refactoring, such as moving classes out of initialization blocks to become ordinary nested classes, or even better, moving them into their own files
The only aspect of this abstract initialization pattern that differs from the refactored version is class visibility You can only get visibility within static {...} blocks But if your course is so complex and long that you are afraid of misuse outside the static {...} block, you will lose anyway