Some classes in the standard Java API are treated slightly different from other classes. I'm talking about those classes that couldn't be implemented without special support from the compiler and/or JVM.
The ones I come up with right away are:
-
Object
(obviously) as it, among other things doesn't have a super class. -
String
as the language has special support for the + operator. -
Thread
since it has this magical start() method despite the fact that there is no bytecode instruction that "forks" the execution.
I suppose all classes like these are in one way or another mentioned in the JLS. Correct me if I'm wrong.
Anyway, what other such classes exist? Is there any complete list of "glorified classes" in the Java language?
There are a lot of different answers, so I thought it would be useful to collect them all (and add some):
Classes
- AutoBoxing classes - the compiler only allows for specific classes
- Class - has its own literals (int.class for instance). I would also add its generic typing without creating new instances.
- String - with it's overloaded +-operator and the support of literals
- Enum - the only class that can be used in a switch statement (soon a privilege to be given to String as well). It does other things as well (automatic static method creation, serialization handling, etc.), but those could theoretically be accomplished with code - it is just a lot of boilerplate, and some of the constraints could not be enforced in subclasses (e.g. the special subclassing rules) but what you could never accomplish without the priviledged status of an enum is include it in a switch statement.
- Object - the root of all objects (and I would add its clone and finalize methods are not something you could implement)
- References: WeakReference, SoftReference, PhantomReference
- Thread - the language doesn't give you a specific instruction to start a thread, rather it magically applies it to the start() method.
- Throwable - the root of all classes that can work with throw, throws and catch, as well as the compiler understanding of Exception vs. RuntimeException and Error.
- NullPointerException and other exceptions such as ArrayIndexOutOfBounds which can be thrown by other bytecode instructions than athrow.
Interfaces
- Iterable - the only interface that can be used in an enhanced for loop
Honorable mentions goes to:
- java.lang.reflect.Array - creating a new array as defined by a Class object would not be possible.
- Annotations They are a special language feature that behaves like an interface at runtime. You certainly couldn't define another Annotation interface, just like you can't define a replacement for Object. However, you could implement all of their functionality and just have another way to retrieve them (and a whole bunch of boilerplate) rather than reflection. In fact, there were many XML based and javadoc tag based implementations before annotations were introduced.
- ClassLoader - it certainly has a privileged relationship with the JVM as there is no language way to load a class, although there is a bytecode way, so it is like Array in that way. It also has the special privilege of being called back by the JVM, although that is an implementation detail.
- Serializable - you could implement the functionality via reflection, but it has its own privileged keyword and you would spend a lot of time getting intimate with the SecurityManager in some scenarios.
Note: I left out of the list things that provide JNI (such as IO) because you could always implement your own JNI call if you were so inclined. However, native calls that interact with the JVM in privileged ways are different.
Arrays are debatable - they inherit Object, have an understood hierarchy (Object[] is a supertype of String[]), but they are a language feature, not a defined class on its own.
Class
, of course. It has its own literals (a distinction it shares with String
, BTW) and is the starting point of all that reflection magic.