Just simply as it sounds. I need to extend their functionality and I cannot. Why are they defined as final?
Example:
class MyInteger extends Integer
{
}
All the wrapper classes are declared final. All the wrapper classes except Boolean and Character are sub classes of an abstract class called Number, Boolean and Character are derived directly from the Object class.
The wrapper class implements the technique to convert the primitive into object and object into primitive. There is a concept of autoboxing and unboxing in the wrapper class, which transform the primitives into objects and objects into primitives automatically.
It is because all primitive wrapper classes (Integer, Byte, Long, Float, Double, Character, Boolean, and Short) are immutable in Java, so operations like addition and subtraction create a new object and not modify the old.
Wrapper classes are basically wrappers around primitive data types. Primitive values in Java don't have the full capabilities of objects. An instance of a wrapper class contains, or wraps, a primitive value of the corresponding type. Wrapper classes are public final i.e. cannot be extended.
There are good reasons to makes the primitive wrappers final.
First, note that these classes get special treatment in the language itself - unlike any normal classes, these are recognized by the compiler to implement auto(un)boxing. Simply allowing subclasses would already create pitfalls (unwrapping a subclass, performing arithmetic and wrapping back would change the type).
Also, wrapper types can have shared instances (e.g. look at Integer.valueOf(int)) requiring that an instance of a wrapper is strictly immutable. Allowing subclasses would open up a can of worms where immutability can no longer be assured, forcing robust code to be written as if the wrappers were mutable, leading to defensive copies, wasting memory and CPU time and also creating issues with their usefulness in multi-threaded scenarios.
Essence: wrapper types need to be immutable to ensure uniform capabilities across all instances; immutablility being an important part of their known properties. And to guarantee immutability, the types need to be final.
If you need added functionality, implement it as utility class like you would do for primitives (see java.lang.Math for example).
Edit: To address the case made for "the classes needn't" be necessary final to ensure immutability. Strictly speaking this is true, the wrappers could be designed as non-final classes, only making all of the methods final. That would alleviate most of the pitfalls, but it leads to another issue: compatibility with new java versions. Imagine you decided to create your own subtype MyInteger sporting a new method, e.g. "Integer decrement()". Everything works fine, until... in Java 20 the language designers decide to add a decrement() method to the API (which would be final as discussed above). Bam, your class no longer loads, since it attempts to overwrite a final method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With