静态块用法内的抽象类

时间:2018-10-07 06:18:17

标签: java abstract-class static-block

我可以在abstract内添加static initialization block关键字,但不能将抽象方法添加为

abstract void draw();

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

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

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

但是在静态块中添加类层次结构(这将比私有级别具有更低的访问级别)听起来不太现实,在静态块中还有abstract的其他用法吗?

1 个答案:

答案 0 :(得分: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();
}

恕我直言,根本不使用静态初始值设定项是例外,这样的庞然大物要求重构,例如将这些类移出初始化块,以成为普通的嵌套类,甚至更好的是,将它们移入它们自己的文件中。

此抽象初始化器模式与重构版本不同的唯一方面是类可见性。您的可见性仅限于static { ... }块内。但是,如果您的班级如此复杂和漫长,以至于您害怕在static { ... }块之外误用,那么您还是输了...

相关问题