我有一个类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 ++中允许使用等价物。
答案 0 :(得分:5)
因为abstract
表示有一些未实现的方法,而final
表示它不能继承。这意味着这个类永远不会有用。如果您的类不包含任何实例方法,只需将其设为final
即可完成:)。无需标记abstract
,因为它不是。您可能还想构建构造函数private
,因此没有人可以实例化它。
例如参见JLS 8.1.1.1:
8.1.1.1。抽象类
抽象类是一个不完整或被认为不完整的类。
[...]
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)
abstract
和final
是Java中的互斥概念。当您将类声明为abstract
时,您说“我打算将此类分类为一个或多个其他类”。当你声明它final
时,你说“我打算这个类不能被任何类扩展”。因此,从Java角度来看,abstract final
类是没有意义的 - 因此语言不允许您首先执行此操作。
针对您的具体用例,为什么不简单地使用enum
?
public enum Severity {
TRACE,
INFORMATION,
WARNING,
ERROR,
CRITICAL_ERROR,
OFF;
}
如果愿意,您可以随时为每个枚举元素包含数值。