静态块使用中的抽象类

use*_*900 7 java abstract-class static-block

我可以在静态初始化块中添加abstract关键字,但我不能添加抽象方法

abstract void draw();
Run Code Online (Sandbox Code Playgroud)

所以我只能在静态块中添加抽象类,如下所示:

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

        @Override
        String test() {
            return null;
        }           
    }
    new Extends().test();
Run Code Online (Sandbox Code Playgroud)

但是在静态块中添加类层次结构并不是真实的,它将在低于私有的访问级别,abstract静态块内是否有其他用法?

Ral*_*off 4

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

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

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

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

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

现在,该类是抽象的,因此为了能够创建实例,我们至少需要一个子类。

如果我们只有一个子类,为什么我们要将其功能分为一个抽象父类和一个子类?这会变得不必要的复杂,所以我们可以假设我们有多个子类。

因此,要在静态初始化块内对关键字进行任何(至少是半理智的)使用abstract,该块必须定义一个抽象父类、多个子类,以及创建这些类的实例的代码,如下面的最小示例:

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();
}
Run Code Online (Sandbox Code Playgroud)

恕我直言,使用静态初始化程序应该是例外,这样的怪物迫切需要重构,例如将类移出初始化块以成为正常的嵌套类,或者更好的是,将它们移动到自己的文件中。

这种抽象初始化器模式与重构版本的唯一不同之处是类可见性。您的可见性仅限于static { ... }块内。但是,如果你的课程如此复杂和冗长,以至于你担心在你的static { ... }街区之外被误用,那么你无论如何都输了......