i gets auto-boxed to an Integer when passed to getObjectSize.

So you get the value of the size of promoted variable, not the original primitive int.

To circumvent this behaviour, build overloads of getObjectSize for the primitive cases:

public static long getObjectSize(int o) {
    return Integer.SIZE / 8;
}

and so on.

Answer from Bathsheba on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › tutorial › java › nutsandbolts › datatypes.html
Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics)
Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency. boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined.
🌐
Quora
quora.com › What-is-the-size-of-an-integer-in-Java
What is the size of an integer in Java? - Quora
* A variable of the int primitive data type takes up 4 bytes (or 32 bits) * An Integer object takes up 16 bytes (or 512 bits) The Integer object is created by the Integer wrapper class and is used for convenience in some places.
🌐
W3Schools
w3schools.com › java › java_data_types.asp
Java Data Types
As explained in the previous chapter, a variable in Java must be a specified data type: int myNum = 5; // Integer (whole number) float myFloatNum = 5.99f; // Floating point number char myLetter = 'D'; // Character boolean myBool = true; // Boolean String myText = "Hello"; // String ·
Top answer
1 of 7
17

Like so many aspects of language design, it comes to a trade-off of elegance against performance (not to mention some historical influence from earlier languages).

Alternatives

It is certainly possible (and quite simple) to make a programming language that has just a single type of natural numbers nat. Almost all programming languages used for academic study (e.g. PCF, System F) have this single number type, which is the more elegant solution, as you surmised. But language design in practice is not just about elegance; we must also consider performance (the extent to which performance is considered depends on the intended application of the language). The performance comprises both time and space constraints.

Space constraints

Letting the programmer choose the number of bytes up-front can save space in memory-constrained programs. If all your numbers are going to be less than 256, then you can use 8 times as many bytes as longs, or used the saved storage for more complex objects. The standard Java application developer does not have to worry about these constraints, but they do come up.

Efficiency

Even if we ignore space, we are still constrained by the CPU, which only has instructions that operate on a fixed number of bytes (8 bytes on a 64-bit architecture). That means even providing a single 8-byte long type would make the implementation of the language significantly simpler than having an unbounded natural number type, by being able to map arithmetic operations directly to a single underlying CPU instructions. If you allow the programmer to use arbitrarily large numbers, then a single arithmetic operation must be mapped to a sequence of complex machine instructions, which would slow down the program. This is point (1) that you brought up.

Floating-point types

The discussion so far has only concerned integers. Floating-point types are a complex beast, with extremely subtle semantics and edge-cases. Thus, even though we could easily replace int, long, short, and byte with a single nat type, it is not clear what the type of floating-point numbers even is. They aren't real numbers, obviously, as real numbers cannot exist in a programming language. They aren't quite rational numbers, either (though it's straight-forward to create a rational type if desired). Basically, IEEE decided on a way to kinda sorta approximate real numbers, and all languages (and programmers) have been stuck with them ever since.

Finally:

Perhaps the programmer wouldn't want someone to be able to use a bigger number than a certain size and this lets them limit it.

This isn't a valid reason. Firstly, I can't think of any situations in which types could naturally encode numerical bounds, not to mention the chances are astronomically low that the bounds the programmer wants to enforce would correspond exactly to the sizes of any of the primitive types.

2 of 7
10

The reason is very simple: efficiency. In multiple ways.

  1. Native data types: The closer the data types of a language match the underlying data types of the hardware, the more efficient the language is considered to be. (Not in the sense that your programs will necessarily be efficient, but in the sense that you may, if you really know what you are doing, write code that will run about as efficient as the hardware can run it.) The data types offered by Java correspond to bytes, words, doublewords and quadwords of the most popular hardware out there. That's the most efficient way to go.

  2. Unwarranted overhead on 32-bit systems: If the decision had been made to map everything to a fixed-size 64-bit long, this would have imposed a huge penalty on 32-bit architectures that need considerably more clock cycles to perform a 64-bit operation than a 32-bit operation.

  3. Memory wastefulness: There is a lot of hardware out there that is not too picky about memory alignment, (the Intel x86 and x64 architectures being examples of that,) so an array of 100 bytes on that hardware can occupy only 100 bytes of memory. However, if you do not have a byte anymore, and you have to use a long instead, the same array will occupy an order of magnitude more memory. And byte arrays are very common.

  4. Calculating number sizes: Your notion of determining the size of an integer dynamically depending on how big the number passed in was is too simplistic; there is no single point of "passing in" a number; the calculation of how large a number needs to be has to be performed at runtime, on every single operation that may require a result of a larger size: every time you increment a number, every time you add two numbers, every time you multiply two numbers, etc.

  5. Operations on numbers of different sizes: Subsequently, having numbers of potentially different sizes floating around in memory would complicate all operations: Even in order to simply compare two numbers, the runtime would first have to check whether both numbers to be compared are of the same size, and if not, resize the smaller one to match the size of the larger one.

  6. Operations that require specific operand sizes: Certain bit-wise operations rely on the integer having a specific size. Having no pre-determined specific size, these operations would have to be emulated.

  7. Overhead of polymorphism: Changing the size of a number at runtime essentially means that it has to be polymorphic. This in turn means that it cannot be a fixed-size primitive allocated on the stack, it has to be an object, allocated on the heap. That is terribly inefficient. (Re-read #1 above.)

🌐
Reddit
reddit.com › r/learnjava › when to use int vs integer ?
r/learnjava on Reddit: When to use int vs Integer ?
August 8, 2021 -
import java.util.*;
class Main {  
  public static void main(String args[]) { 
	Integer[] a = {1,2};
	int[] b = {1,2};
	System.out.println(Arrays.toString(a));
	System.out.println(Arrays.toString(b));

  } 
}

Hi all, trying to learn Java from python background and run into some trouble.

So I have read that Integer is the object class and int is the binary primitive, and that Java compiler is now able to convert between them when nesessary.

But when should I use the primitive vs the object ? Generally speaking, all I can think of right now is that we should always use the primitives unless we may need to cast to another type in the future so then use object ones.

Find elsewhere
🌐
Reddit
reddit.com › r/javahelp › int array memory size
r/javahelp on Reddit: int array memory size
March 12, 2017 -

How many bytes does an int[] vs. Integer[] be in memory? Like including the overhead and extra data required, not just the data itself? I know it has an additional length which is an int (8 bytes).

Top answer
1 of 3
4

A primitive int obviously takes 4 byte.

An Integer object has an overhead of about 24 byte (this is implementation specific) plus 4 byte for the data, so about 28 byte.

An array is an object which also has an overhead of 24 bytes plus 4 bytes for the length plus data.

An int[] array thus uses 28 bytes plus 4 bytes for each int.

An Integer[] array uses 28 bytes plus 4-8 bytes to reference each Integer object plus 28 byte for each unique Integer object. In the worst case with uncached and unique Integer objects, this equals to 28 bytes array overhead plus 36 bytes for each value.

2 of 3
2

There are two things you have to take into account here:

  1. Overhead for the data itself (int vs. Integer)

  2. Overhead for the object reference

So, let's start :)

  1. Integer vs. int.

Primitive int is just a 4 bytes value (not 8 bytes as you've written). Integer is an object, which consists of a primitive int value (4 bytes) and object header. Object header can be 8, 12, or 16 bytes depending on the bitness of your JVM and UseCompressedOops flag. Here is Stackoverflow answer that describes the structure of the object header: https://stackoverflow.com/questions/26357186/what-is-in-java-object-header

UseCompressedOops is a flag that makes JVM optimize most of the references on 64-bit JVM and make them take 32 bits instead of 64 bits. If set, it should also make object header take 12 bytes instead of 16 bytes. (To be honest, I didn't measure this).

Given that, the overhead for a bunch of integers will be

number_of_elements * object_header_overhead

, where object_header_overhead =

  • 8 bytes (on 32 bit JVM)

  • 12 bytes (on 64 bit JVM with UseCompressedOops = true)

  • 16 bytes (on 64 bit without compressed oops)

But that's not the end of the story.

2. Size of object reference

int is a primitive, in another words it's just 4 bytes of data, and that's it. Integer is an object, which means it should be referenced from some another place in your program. If it is not referenced from anywhere, it's lost (and soon will be eaten by the GC).

Now, if you have an array of ints, then each element of it is a 4 byte int value. If you have an array of Integers, each element of it will be not Integer, but a reference to Integer object.

The size of an object reference is also can be different on different JVMs:

- 32 bits on 32 bit JVM

- 64 bits on 64 bit JVM

- 32 bits on 64 bit JVM with UseCompressedOops

Now you can calculate total overhead for your specific case. Here are few examples:

  1. Say, you run the following code on 32 bit JVM:

i1 = new Integer[100];
i2 = new int[100];

These are just empty arrays. The memory taken by them will be exactly the same, because each element of each array will take 4 bytes (0 int is 4 bytes, and null is 32 bits on 32 bit JVM).

2. Now, say you have 64 bit JVM without compressed oops.

i1 = new Integer[100];
i2 = new int[100];

for (int i = 0; i < 100; i++) {
  i1[i] = i; // implicit boxing: new Integer(i);
  i2[i] = i;
}

Now the memory taken by a single element of Integer array will consist of:

  • 4 bytes int value

  • 16 bytes - object header

  • 8 bytes object reference,

while an element of int array will only take 4 bytes. In total you have (16 + 8) * 100 = 240 bytes.

3. Of course, you can have more complicated situations, for instance (let's say, we have 64 bit JVM again):

i1 = new Integer[100];
i2 = new int[100];

int primInt = 42;
Integer wrappedInt = new Integer(42);

for (int i = 0; i < 100; i++) {
  i1[i] = wrappedInt;
  i2[i] = primInt;
}

As you can see, now every element of Integer array references a single Integer object. So, the total memory overhead will consist of:

  • 100 * 4 bytes (4 bytes for primitive int vs. 8 bytes for object reference on 64 bit JVM)

  • 20 bytes (size of the single Integer object, consisting of 16 bytes for the header and 4 bytes for the int value).

And couple more things to add:

  1. I don't guarantee that the information about the size of object header is 100% correct. This is what I remember about it, so please verify it yourself if you need to.

  2. Things can get even more complicated, because Java tends to cache Integers and reuse them. So actual memory of your programs can be less than expected.

🌐
GeeksforGeeks
geeksforgeeks.org › java › difference-between-byte-short-int-and-long-datatype-in-java
Difference Between byte, short, int and long Datatype in Java - GeeksforGeeks
July 23, 2025 - The integer data types are used to store numeric values. In this article, we will discuss the difference between these four Integer data-types. JAVA does not support an unsigned version of these integer data types. The main basis of difference is size and range.
🌐
Kotlin Discussions
discuss.kotlinlang.org › t › does-int-has-something-akin-to-java-lang-integer-size › 8705
Does Int has something akin to java.lang.Integer.SIZE? - Kotlin Discussions
May 18, 2018 - Int has the same MAX_VALUE and MIN_VALUE properties as java.lang.Integer but doesn’t appear to have a SIZE equivalent (the number of bits). I’m doing my bit arithmetic with Int’s but referencing java.lang.Integer.SIZE, which looks a bit wacky but it was that or code it as 32. java.lang.Integer has a lot of good stuff in there.
🌐
BeginnersBook
beginnersbook.com › 2024 › 06 › how-to-find-size-of-an-int-in-java
How to Find Size of an int in Java
Integer.SIZE returns the number of bits required to represent an int. Since 8 bits equal to 1 bytes, dividing the retuned value by 8 converts the size from bits to bytes. ... This confirms that the size of int in Java is 4 bytes.
Top answer
1 of 10
104

the Integer class is provided so that values can be boxed/unboxed in a pure OO manner. use int where appropriate unless you specifically need to use it in an OO way; in which case Integer is appropriate.

Java Int vs Integer

However, very different things are going on under the covers here. An int is a number; an > Integer is a pointer that can reference an object that contains a number.

...

An int is not an object and cannot passed to any method that requires objects. A common case is in using the provided collection classes ( List , Map , Set ) - though it is possible to write versions of these classes that provide similar capabilities to the object versions. The wrapper classes ( Integer , Double , etc) are frequently required whenever introspection is used (such as in the reflection API).

A better description of when to use one vs. the other:

Choosing between int and Integer

I'll start with how these types should be used before going into detail on why.

  • Prefer int for performance reasons
  • Methods that take objects (including generic types like List<T>) will implicitly require the use of Integer
  • Use of Integer is relatively cheap for low values (-128 to
  1. because of interning - use Integer.valueOf(int) and not new Integer(int)
  • Do not use == or != with Integer types
  • Consider using Integer when you need to represent the absence of a value (null)
  • Beware unboxing Integer values to int with null values
2 of 10
43

If you can use int do so. If the value can be null or is used as an Object e.g. Generics, use Integer

Usually it doesn't matter which one you use but often int performs slightly better.

🌐
CodeGym
codegym.cc › java blog › java classes › java.lang.integer class
Java.lang.Integer Class
February 20, 2025 - Exception in thread "main" java.lang.NullPointerException" The Integer class provides various constants and methods for working with integers. Here they are: SIZE means the number of bits in the two-digit number system occupied by the type int
🌐
Dot Net Perls
dotnetperls.com › integer-java
Java - Integer Max, Min and Size - Dot Net Perls
Info Type returns a class reference. This matches the shortened type, like int for Integer. Next Size returns the numbers of bits in the type.
🌐
IBM
ibm.com › docs › en › i › 7.4.0
COBOL and Java Data Types
We cannot provide a description for this page right now
🌐
TheServerSide
theserverside.com › blog › Coffee-Talk-Java-News-Stories-and-Opinions › int-vs-Integer-java-difference-comparison-primitive-object-types
Integer vs. int: What's the difference?
The key difference between the Java int and Integer types is that an int simply represents a whole number, while an Integer has additional properties and methods.
Top answer
1 of 11
450

In C, the language itself does not determine the representation of certain datatypes. It can vary from machine to machine, on embedded systems the int can be 16 bit wide, though usually it is 32 bit.

The only requirement is that short int <= int <= long int by size. Also, there is a recommendation that int should represent the native capacity of the processor.

All types are signed. The unsigned modifier allows you to use the highest bit as part of the value (otherwise it is reserved for the sign bit).

Here's a short table of the possible values for the possible data types:

          width                     minimum                         maximum
signed    8 bit                        -128                            +127
signed   16 bit                     -32 768                         +32 767
signed   32 bit              -2 147 483 648                  +2 147 483 647
signed   64 bit  -9 223 372 036 854 775 808      +9 223 372 036 854 775 807
unsigned  8 bit                           0                            +255
unsigned 16 bit                           0                         +65 535
unsigned 32 bit                           0                  +4 294 967 295
unsigned 64 bit                           0     +18 446 744 073 709 551 615

In Java, the Java Language Specification determines the representation of the data types.

The order is: byte 8 bits, short 16 bits, int 32 bits, long 64 bits. All of these types are signed, there are no unsigned versions. However, bit manipulations treat the numbers as they were unsigned (that is, handling all bits correctly).

The character data type char is 16 bits wide, unsigned, and holds characters using UTF-16 encoding (however, it is possible to assign a char an arbitrary unsigned 16 bit integer that represents an invalid character codepoint)

          width                     minimum                         maximum

SIGNED
byte:     8 bit                        -128                            +127
short:   16 bit                     -32 768                         +32 767
int:     32 bit              -2 147 483 648                  +2 147 483 647
long:    64 bit  -9 223 372 036 854 775 808      +9 223 372 036 854 775 807

UNSIGNED
char     16 bit                           0                         +65 535
2 of 11
84

In C, the integer(for 32 bit machine) is 32 bit and it ranges from -32768 to +32767.

Wrong. 32-bit signed integer in 2's complement representation has the range -231 to 231-1 which is equal to -2,147,483,648 to 2,147,483,647.