[英]Why is public abstract final class syntactically invalid?
我有一个类foo
,它只是一个static
函数和变量的占位符。 有点像C ++中的namespace
。
因此,创建foo
的实例并从foo
继承是没有意义的。
所以我很想写public abstract final class foo
。 但Java不喜欢这样。 我可以在C ++中使用纯虚函数和final
函数来final
,但为什么我不能在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 ++中允许等效。
因为abstract
说有一些未实现的方法和final
状态,它不能从中继承。 这意味着这个类永远不会有用。 如果你的类不包含任何实例方法,那就让它final
完成并且你已经完成了:)。 不需要将其标记为abstract
因为它不是。 您可能还希望将构造函数设置为private
因此没有人可以实例化它。
例如,参见JLS 8.1.1.1 :
8.1.1.1。 抽象类
抽象类是一个不完整的类,或者被认为是不完整的类。
[...]
8.1.1.2。 最后的课程
[...]
如果一个类被声明为final和abstract,那么这是一个编译时错误,因为这样一个类的实现永远无法完成(§8.1.1.1)。
您可以使用空枚举代替类
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;
}
你不能实例化枚举,你不能扩展枚举。 因此它可以为您提供所需的一切
在Java中,如果要编写既不能实例化也不能扩展的类,请使用private
构造函数
private MyClass() {}
可以说应该有一种在类声明中指定它的方法,但是没有。
当你把一个类称为final时,它表示无法扩展类,需要扩展一个抽象类。 所以它是一个逻辑上的矛盾。
编辑:
编辑似乎很好,你的代码看起来很好。 您无法实例化Severity,因为它是抽象的,因此您可以将变量作为final。
abstract
和final
是Java中相互排斥的概念。 当你声明一个类是abstract
,你会说“我打算让这个类被一个或多个其他类子类化”。 当你宣告它是final
,你会说“我打算这个类不能被任何类扩展”。 因此,从Java的角度来看, abstract final
类没有任何意义 - 因此语言不允许您首先执行此操作。
对于您的特定用例,为什么不简单地使用enum
?
public enum Severity {
TRACE,
INFORMATION,
WARNING,
ERROR,
CRITICAL_ERROR,
OFF;
}
如果您愿意,您始终可以为每个枚举元素包含数值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.