为什么公共抽象最终类在语法上无效?

时间:2015-10-15 13:14:02

标签: java

我有一个类foo,它只是一个static函数和变量的占位符。有点像C ++中的namespace

创建foo的实例并继承自foo因此毫无意义。

所以我很想写public abstract final class foo。但Java不喜欢这样。我可以使用纯虚函数和final在C ++中完成它,但为什么我不能在Java中执行相同的操作?我的设计出了什么问题?

更新 我在这方面受到了严重的贬低(写作时为-4)所以我显然还不够清楚。这是具体的用例。这是在JNI和支持C库中使用的错误日志记录的严重级别代码的加载:

public abstract class Severity
{ 
    public static final int TRACE = 0x00000001;

    public static final int INFORMATION = 0x00000002;

    public static final int WARNING = 0x00000003;

    public static final int ERROR = 0x00000004;

    public static final int CRITICAL_ERROR = 0x00000005;

    public static final int OFF = 0x00000006;
}

所以它几乎就像一个枚举器,但JNI和C库限制意味着它不是最理想的。这个abstract final似乎对我来说是完全合理的,而且正如我所说的那样,C ++中允许使用等价物。

5 个答案:

答案 0 :(得分:5)

因为abstract表示有一些未实现的方法,而final表示它不能继承。这意味着这个类永远不会有用。如果您的类不包含任何实例方法,只需将其设为final即可完成:)。无需标记abstract,因为它不是。您可能还想构建构造函数private,因此没有人可以实例化它。

例如参见JLS 8.1.1.1

  

8.1.1.1。抽象类

     

抽象类是一个不完整或被认为不完整的类。

     

[...]

JLS 8.1.1.2

  

8.1.1.2。最后的课程

     

[...]

     

如果一个类被声明为final和abstract,那么这是一个编译时错误,因为这样一个类的实现永远无法完成(§8.1.1.1)。

答案 1 :(得分:3)

您可以使用空枚举代替类

public enum Severity
{ ;
    public static final int TRACE = 0x00000001;

    public static final int INFORMATION = 0x00000002;

    public static final int WARNING = 0x00000003;

    public static final int ERROR = 0x00000004;

    public static final int CRITICAL_ERROR = 0x00000005;

    public static final int OFF = 0x00000006;
}

你不能实例化枚举,你不能扩展枚举。因此它可以为您提供所需的一切

答案 2 :(得分:2)

在Java中,如果要编写既不能实例化也不能扩展的类,请使用private构造函数

private MyClass() {}

可以说应该有一种在类声明中指定它的方法,但是没有。

答案 3 :(得分:0)

当你把一个班级称为最后一个班级时,这意味着不能扩展班级,需要扩展抽象班级。所以这是一个逻辑上的矛盾。

修改

编辑似乎很好,你的代码看起来不错。您无法实例化Severity,因为它是抽象的,因此您可以将变量设置为final。

答案 4 :(得分:-1)

abstractfinal是Java中的互斥概念。当您将类声明为abstract时,您说“我打算将此类分类为一个或多个其他类”。当你声明它final时,你说“我打算这个类不能被任何类扩展”。因此,从Java角度来看,abstract final类是没有意义的 - 因此语言不允许您首先执行此操作。

针对您的具体用例,为什么不简单地使用enum

public enum Severity {
    TRACE,
    INFORMATION,
    WARNING,
    ERROR,
    CRITICAL_ERROR,
    OFF;
}

如果愿意,您可以随时为每个枚举元素包含数值。