Java 为什么公共抽象final类在语法上是无效的?

Java 为什么公共抽象final类在语法上是无效的?,java,Java,我有一个类foo,它只不过是一些静态函数和变量的占位符。在C++中有点像命名空间< /代码> 因此,创建foo的实例和从foo继承是毫无意义的 所以我想写公共抽象最终类foo。但是Java不喜欢这样。我可以用C++的纯函数和最终< /COD>来做,但是为什么我不能用java做等价物呢?我的设计有什么问题 更新: 在这个问题上,我的支持率很低(撰写本文时为-4),所以我显然还不够清楚。下面是具体的用例。在JNI和支持C库中使用了大量用于错误日志记录的严重级别代码: public abstract

我有一个类
foo
,它只不过是一些
静态
函数和变量的占位符。在C++中有点像<代码>命名空间< /代码> 因此,创建
foo
的实例和从
foo
继承是毫无意义的

所以我想写
公共抽象最终类foo
。但是Java不喜欢这样。我可以用C++的纯函数和<代码>最终< /COD>来做,但是为什么我不能用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库的限制意味着这是次优的。使这个<代码>抽象< /> > <强> >代码>最终< /代码>对我来说似乎完全合理,并且正如我所说,在C++中是等价的。

因为<代码>抽象<代码>说,它有一些未实现的方法和<代码>最终< /代码>,表示它不能继承。这意味着这个类永远不会有用。如果您的类不包含任何实例方法,只需将其设置为
final
即可:)。不需要标记它,因为它不是抽象的。您可能还希望将构造函数设置为私有的,这样就没有人可以实例化它了

例如,见:

8.1.1.1。抽象类

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

[……]

8.1.1.2。期末班

[……]

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


在一行中,当你说一个类是final时,它意味着这个类不能被扩展,一个抽象类需要被扩展。因此,这是一个逻辑矛盾

编辑:


编辑看起来不错,代码看起来也不错。您不能实例化严重性,因为它是抽象的,所以您可以将变量作为最终变量。

在Java中,如果您想编写一个既不能实例化也不能扩展的类,请使用
私有构造函数

private MyClass() {}

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

abstract
final
在Java中是相互排斥的概念。当您将一个类声明为抽象类时,您的意思是“我希望这个类被一个或多个其他类子类化”。当您声明它为final时,您的意思是“我希望这个类不能被任何类扩展”。因此,从Java的角度来看,
抽象final
类毫无意义,因此该语言首先不允许您这样做

对于您的特定用例,为什么不简单地使用
enum

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

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

您可以使用空枚举来代替类

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;
}

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

,据我所知,这应该是一个
公共静态类
,而您的方法应该是
静态的
。还要添加一个私有构造函数。Utlity类。因为
abstract
final
是互斥的。将类声明为
abstract
是您打算扩展该类的一个标志。声明它为final表示您不能扩展这个类。这是一个好问题。人们很快就否决了投票。其他语言有声明类的方法,不能实例化或扩展。一点也不能。我可以用C++做,而且对我来说是有用的。标记构造函数私有是一种设计,它可以被反射来规避。实际上,我提到C++,以确定与我想做的没有什么根本错误或矛盾。C++(java)和Java中的代码>抽象>代码>的语义很可能是不同的。是的,你是正确的。C++实际上没有<代码>抽象>代码>:你可以通过至少一个纯虚函数,即没有定义的函数来生成类<代码>抽象>代码>。但据我所知,校长是一样的。不,不是。我的具体案例是有效的。@p45:-是的,我看到了编辑。更新了我的答案。但我也不希望有人继承它并插入其他代码。我只想要一个C++命名空间!我不确定是什么阻止了您创建枚举?让我试试这个。我不认为它把JNI搞砸了。这绝对是太棒了,
做什么?@p459
用于从枚举成员中分离枚举值。您在这里要做的是,创建一个没有值的枚举,其中包含一些静态字段。@p45枚举中的第一件事通常是枚举元素列表,以逗号分隔,并以分号结尾。这里的分号终止了枚举元素的(不存在的)列表,留下一个空枚举。@P45您不喜欢私有构造函数答案的原因是它可以通过反射绕过,但是您也可以使用反射来实例化这个
enum
版本。这是定义不能在Java中实例化的类的正确习惯用法。
abstract
enum
都有不同的语义。