abstract class 内部静态块用法

abstract class inside static block usage

我可以添加 abstract keyword inside static initialization block,但我不能添加抽象方法

abstract void draw();

所以我只能在static块里面加抽象class,如下:

static {
    abstract class Abstract { 
        abstract String test();
    }
    class Extends extends Abstract {

        @Override
        String test() {
            return null;
        }           
    }
    new Extends().test();

但是在静态块中添加 classes 层次结构听起来不现实,它的访问级别低于私有,在静态块中还有其他用法 abstract 吗?

TL;DR 此功能没有合理的用法。如果我在代码审查中看到这个,我会强迫作者重构它。

有时,Java 规范允许您在正常的生产代码中编写不应该做的事情,对我来说,这就是一个例子。

让我们尝试推导出一个使用此功能的代码片段。

我们可以在静态初始化块中使用 abstract 关键字。这只能在定义 class 时通过声明 class 本身 abstract 以及可选的某些方法来完成。

这个 class 在初始化块之外是不可见的,因此我们可以推断我们将在内部使用它。 abstract 都是关于创建实例或定义实例方法的。因此,只有当我们计划创建抽象 class.

的实例时它才有用

现在,class 是抽象的,所以为了能够创建实例,我们至少需要一个子class。

如果我们只有一个子class,为什么我们要把它的功能分成抽象的parent和一个childclass?这将是不必要的复杂,所以我们可以假设我们有多个 child classes.

因此,要在静态初始化块中(至少 half-sane)使用 abstract 关键字,该块必须定义一个抽象 parent class ,多个 child classes,加上创建这些 classes 实例的代码,例如这个最小示例:

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();
}

恕我直言,完全使用静态初始化程序应该是个例外,这样的怪物会哭着进行重构,例如将 classes 从初始化块中移出,成为普通的嵌套 classes,或者更好的是,将它们移到自己的文件中。

此 abstract-in-initializer 模式与重构版本的唯一不同之处在于 class 可见性。您的可见性仅限于 static { ... } 块内。但是如果你的 class 太复杂太长以至于你害怕 mis-use 在你的 static { ... } 块之外,那么你已经输了......