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.

Answer from Durandal on Stack Overflow
Top answer
1 of 5
22

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.

2 of 5
5

This is a security feature that lets libraries use strings and wrappers for primitives in collections or otherwise without making "defensive copies".

If users were allowed to derive their own values, say, from Integer, they could make a mutable version of it. Then they could pass instances of this Integer to a library that expects a collection of Integers, like this:

class ApiClass {
    private final List<Integer> intList;
    ApiClass (List<Integer> ints) {
        // Make a defensive copy
        intList = new ArrayList<Integer>(ints);
        // Go through the list, and check the values
        ...
    }
}

Currently the constructor should make a defensive copy of the collection, but a shallow copy is sufficient, because Integers inside cannot change. If Java did not insist on Integer being final, however, there would be no such guarantee, so the code would have to make a deep copy. Otherwise the caller could construct ApiClass by passing valid Integers in a list, and then go through that list of MyIntegers, and change their values to what the constructor would consider invalid. This would break assumptions of other methods inside ApiClass, potentially causing crashes or exposing information that the "plain" Integer would not leak.

🌐
C# Corner
c-sharpcorner.com › blogs › wrapper-classes-in-java1
Wrapper Classes in JAVA
September 28, 2019 - All the wrapper classes are declared final.
🌐
Scientech Easy
scientecheasy.com › home › blog › wrapper classes in java (with examples)
Wrapper Classes in Java (with Examples) - Scientech Easy
February 3, 2025 - These wrapper classes are defined in java.lang package. All the wrapper classes are immutable and final in Java whose objects each hold a single primitive value.
🌐
Gopi Gorantala
ggorantala.dev › what-are-wrapper-classes-in-java
What Are Wrapper Classes in Java? - Gopi Gorantala
October 3, 2023 - Primitive wrappers, also known as wrapper classes, are a set of classes in Java that provide an object representation for the primitive data types. Wrapper classes are all final, so once created, you cannot alter the underlying value. They are ...
🌐
Coderanch
coderanch.com › t › 377306 › java › Wrapper-Classes-String-final
Why are Wrapper Classes, String,... final ? (Java in General forum at Coderanch)
July 22, 2005 - programming forums Java Mobile ... Other Pie Elite all forums · this forum made possible by our volunteer staff, including ... ... Many classes in the Core Java API are final (Wrapper classes, String, Math)....
Top answer
1 of 1
7

Whenever you don't want the class to be extended. Designing for extension has a cost (see also Eric Lippert's Blog: Why Are So Many Of The Framework Classes Sealed?) - you need to make sure you provide the right hooks for the class, that people can implement those hooks without breaking things, that you can be reasonably sure that subclasses won't be nefarious (this is especially important with core language classes like String and Integer), that the contracts that the superclasses implement are clear (so that subclasses don't break them easily).

This takes work, time, and thought to put into it. It isn't easy developing a class that is meant to be extended. And sometimes, you know you don't want it to be extended - that it can be put to nefarious use and cause havoc with your implementation if someone passes you a mutable String rather than an immutable one.

And so, you make the classes final. There can be no mutable String, because its an immutable class and its final. You know when you get it, it won't be changed from under you in some way. You can save it and be sure that that it will behave like a String, always - no subclasses can be made to make it be otherwise.

Thus, there is a bit of design that some follow that all classes start out as default to be final. How often are you going to subclass that DTO? And when you do want to subclass it for some reason, you should spend some time thinking about the implications of removing the modifier.

There is a check style rule Design For Extension. Personally, I like it. In every non-final class, every method must be one of:

  • abstract
  • final
  • empty implementation

This sort of thinking then allows you to write subclasses that are clearly implemented the proper way - providing hooks and preventing the superclass fro being broken by the subclass not knowing about tinkering the innards of it in an unexpected way. Though, admittedly, this design philosophy means that the subclasses are more limited in their flexibility - but they can't corrupt the state of their superclass.

Again, if you're not prepared or willing to design a class so that it can be extended cleanly, it is best to design the class so it can't be extended at all.

🌐
The IoT Academy
theiotacademy.co › home › explain java wrapper classes with examples – beginners guide
Explain Java Wrapper Classes with Examples - Beginners Guide - Tech & Career Blogs
June 16, 2025 - Make all mutable fields final. This will ensure that a field's value can only be assigned once. Use a constructor method that performs deep copy to initialize all fields. Return a copy after cloning the objects in the getter methods.
Find elsewhere
🌐
Career Ride
careerride.com › question-23-java
All the wrapper classes (Integer, Boolean, Float, Short, Long, Double and Character) in java - java
All the wrapper classes (Integer, Boolean, Float, Short, Long, Double and Character) in java CORRECT ANSWER : are final
🌐
Scaler
scaler.com › home › topics › final class in java
Final Class in Java | Scaler Topics
May 28, 2024 - We can only create a final class if it is complete, which means it cannot be an abstract class. All wrapper classes in Java are final classes, such as String, Integer, etc.
🌐
Coderanch
coderanch.com › t › 684494 › java › wrapper-class
wrapper class (Java in General forum at Coderanch)
September 10, 2017 - Integer Byte Short Long Boolean Float Double Character All the java wrapper classes are by default final and immutable. Autoboxing : Automatic conversion of primitive types to object in known as autoboxing. for example : int to Integer, double to double, etc.
🌐
sghoshbooks
techguruspeaks.com › wrapper-classes-in-java
Wrapper classes in Java - TechGuruSpeaks
April 24, 2020 - 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. Wrapper classes allow objects to be created from primitive types.
🌐
GeeksforGeeks
geeksforgeeks.org › java › wrapper-classes-java
Wrapper Classes in Java - GeeksforGeeks
Wrapper classes are required in Java for the following reasons: Java collections (ArrayList, HashMap, etc.) store only objects, not primitives. Wrapper objects allow primitives to be used in object-oriented features like methods, synchronization, and serialization.
Published   April 6, 2026
🌐
Medium
medium.com › @gauravshah97 › wrapper-classes-in-java-0c5d9205f3b3
Wrapper Classes in Java
April 26, 2024 - A Wrapper class in Java is one whose object wraps or contains primitive data types. Wrapper classes help you write cleaner code, which is easy to read. ... Java collection framework works with objects only. All classes of the collection framework (ArrayList, LinkedList, HashSet, etc.) deal with objects only.
🌐
Javatpoint
javatpoint.com › wrapper-class-in-java
Wrapper class in Java
May 29, 2014 - final keyword · Runtime Polymorphism · Dynamic Binding · instanceof operator · Abstract class in Java · Interface in java · Abstract vs Interface · Java Package · Access Modifiers · Encapsulation · Java Array · Object class · Object Cloning · Math class · Wrapper Class ·
🌐
Medium
medium.com › @bpnorlander › java-understanding-primitive-types-and-wrapper-objects-a6798fb2afe9
Java: Understanding Primitive Types and Wrapper Objects | by Brian Norlander | Medium
March 19, 2019 - All primitive wrapper objects in Java are final, which means they are immutable. When a wrapper object get its value modified, the compiler must create a new object and then reassign that object to the original.
🌐
Whizlabs
whizlabs.com › home › ocajp – wrapper classes in java
OCAJP - Wrapper Classes in Java - Whizlabs Blog
May 10, 2024 - There are certain situations to ... value in an object. Hence the name “Wrapper Classes”. All wrapper classes are immutable classes....
🌐
W3Schools
w3schools.com › java › java_wrapper_classes.asp
Java Wrapper Classes
Java Examples Java Videos Java Compiler Java Exercises Java Quiz Java Code Challenges Java Practice Problems Java Server Java Syllabus Java Study Plan Java Interview Q&A ... Wrapper classes provide a way to use primitive data types (int, boolean, etc..) as objects.
🌐
GeeksforGeeks
geeksforgeeks.org › java › primitive-wrapper-classes-are-immutable-in-java
Primitive Wrapper Classes are Immutable in Java - GeeksforGeeks
August 30, 2022 - 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.