I have a class foo
that is no more than a placeholder for a few static
functions and variables. A bit like a namespace
in C++.
Creating an instance of foo
and inheriting from foo
are therefore meaningless.
So I'm tempted to write public abstract final class foo
. But Java dislikes that. I can do it in C++ with a pure virtual function and final
, but why can't I do the equivalent in Java? What's so wrong with my design?
Update: I'm getting heavily downvoted on this (-4 at the time of writing) so I obviously haven't been clear enough. Here's the specific use case. It's a load of severity level codes for error logging that's used in a JNI and supporting C library:
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;
}
So it's almost like an enumerator but the JNI and C library restrictions mean that would be suboptimal. Making this abstract
and final
seems perfectly reasonable to me, and, as I've said, the equivalent is permissible in C++.
Because abstract
says that is has some unimplemented methods and final
states that it cannot be inherited from. That means this class can never be useful. If your class does not contain any instance methods, just make it final
and you're done :). No need to mark it abstract
because it isn't. You probably also want to make the constructor private
so no one can instantiate it.
See for example the JLS 8.1.1.1 :
8.1.1.1. abstract Classes
An abstract class is a class that is incomplete, or to be considered incomplete.
[...]
and JLS 8.1.1.2
8.1.1.2. final Classes
[...]
It is a compile-time error if a class is declared both final and abstract, because the implementation of such a class could never be completed (§8.1.1.1).
You could use empty enum instead class
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;
}
you cant instantiate enum, you can't extend enum. hence it gives you all what you want
In Java, if you want to write a class that can neither be instantiated nor extended, use a private
constructor
private MyClass() {}
Arguably there should be a way of specifying this in the class declaration, but there isn't.
In a one liner when you say a class as final then it means that class can't be extended, an abstract class needs to be extended. So its a logical contradiction.
EDIT:
The edit seems fine and your code looks good. You cannot instantiate Severity because of it abstract so you can have the variables as final.
abstract
and final
are mutually-exclusive concepts in Java. When you declare a class to be abstract
, you are saying "I intend for this class to be subclassed by one or more other classes". When you declare it final
, you're saying "I intend that this class cannot be extended by any class". As such, an abstract final
class makes no sense from a Java perspective - so the language doesn't permit you to do it in the first place.
For your specific use-case, why not simply use an enum
?
public enum Severity {
TRACE,
INFORMATION,
WARNING,
ERROR,
CRITICAL_ERROR,
OFF;
}
You can always include numeric values for each enum element if you wish.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.