No. There is no such method in the standard Java SE class library.
The designers' view is that it is not needed in Java, since the language removes the need for an application1 to know about how much space needs to be reserved for a primitive value, an object or an array with a given number of elements.
You might think that a sizeof operator would be useful for people that need to know how much space their data structures take. However you can also get this information and more, simply and reliably using a Java memory profiler, so there is no need for a sizeof method.
Previous commenters made the point that sizeof(someType) would be more readable than 4. If you accept that readability argument, then the remedy is in your hands. Simply define a class like this ...
public class PrimitiveSizes {
public static int sizeof(byte b) { return 1; }
public static int sizeof(short s) { return 2; }
// etcetera
}
... and statically import it ...
import static PrimitiveSizes.*;
Or define some named constants; e.g.
public static final int SIZE_OF_INT = 4;
Or (Java 8 and later) use the Integer.BYTES constant, and so on.
Why haven't the Java designers implemented this in standard libraries? My guess is that:
they don't think there is a need for it,
they don't think there is sufficient demand for it, and
they don't think it is worth the effort.
There is also the issue that the next demand would be for a sizeof(Object o) method, which is fraught with technical difficulties.
The key word in the above is "they"!
1 - A programmer may need to know in order to design space efficient data structures. However, I can't imagine why that information would be needed in application code at runtime via a method call.
I don't think it is in the java API. but most datatypes which have a number of elements in it, have a size() method. I think you can easily write a function to check for size yourself?
A superficial answer is that Java does not provide anything like C's sizeof(). However,
let's consider why a Java programmer might occasionally want it.
A C programmer manages most datastructure memory allocations himself,
and sizeof() is indispensable for knowing memory block sizes to
allocate. Additionally, C memory allocators like malloc() do almost
nothing as far as object initialization is concerned: a programmer
must set all object fields that are pointers to further objects. But
when all is said and coded, C/C++ memory allocation is quite
efficient.
By comparison, Java object allocation and construction are tied
together (it is impossible to use an allocated but uninitialized
object instance). If a Java class defines fields that are references
to further objects, it is also common to set them at construction
time. Allocating a Java object therefore frequently allocates numerous
interconnected object instances: an object graph. Coupled with
automatic garbage collection, this is all too convenient and can make
you feel like you never have to worry about Java memory allocation
details.
Of course, this works only for simple Java applications. Compared with
C/C++, equivalent Java datastructures tend to occupy more physical
memory. In enterprise software development, getting close to the
maximum available virtual memory on today's 32-bit JVMs is a common
scalability constraint. Thus, a Java programmer could benefit from
sizeof() or something similar to keep an eye on whether his
datastructures are getting too large or contain memory bottlenecks.
Fortunately, Java reflection allows you to write such a tool quite
easily.
Before proceeding, I will dispense with some frequent but incorrect
answers to this article's question. Fallacy: Sizeof() is not needed
because Java basic types' sizes are fixed
Yes, a Java int is 32 bits in all JVMs and on all platforms, but this
is only a language specification requirement for the
programmer-perceivable width of this data type. Such an int is
essentially an abstract data type and can be backed up by, say, a
64-bit physical memory word on a 64-bit machine. The same goes for
nonprimitive types: the Java language specification says nothing about
how class fields should be aligned in physical memory or that an array
of booleans couldn't be implemented as a compact bitvector inside the
JVM. Fallacy: You can measure an object's size by serializing it into
a byte stream and looking at the resulting stream length
The reason this does not work is because the serialization layout is
only a remote reflection of the true in-memory layout. One easy way to
see it is by looking at how Strings get serialized: in memory every
char is at least 2 bytes, but in serialized form Strings are UTF-8
encoded and so any ASCII content takes half as much space
The Java Native Access library is typically used for calling native shared libraries from Java. Within this library there exist methods for determining the size of Java objects:
The Instrumentation class has a getObjectSize() method however, you shouldn't need to use it at runtime. The easiest way to examine memory usage is to use a profiler which is designed to help you track memory usage.
EhCache provides a SizeOf class that will try to use the Instrumentation agent and will fall back to a different approach if the agent is not loaded or cannot be loaded (details here).
You can do bit manipulations like below to obtain the size of primitives:
public int sizeofInt() {
int i = 1, j = 0;
while (i != 0) {
i = (i<<1); j++;
}
return j;
}
public int sizeofChar() {
char i = 1, j = 0;
while (i != 0) {
i = (char) (i<<1); j++;
}
return j;
}
There's a class/jar available on SourceForge.net that uses Java instrumentation to calculate the size of any object. Here's a link to the description: java.sizeOf
I decided to create an enum without following the standard Java conventions. Perhaps you like this.
public enum sizeof {
;
public static final int FLOAT = Float.SIZE / 8;
public static final int INTEGER = Integer.SIZE / 8;
public static final int DOUBLE = Double.SIZE / 8;
}
It returns an implementation-specific approximation of the amount of storage consumed by the specified object. The result may include some or all of the object's overhead, and thus is useful for comparison within an implementation but not between implementations. The estimate may change during a single invocation of the JVM.
public class PrimitiveTypesV2 {
public static void main (String[] args) {
Class typesList[] = {
Boolean.class , Byte.class, Character.class, Short.class, Integer.class,
Long.class, Float.class, Double.class, Boolean.TYPE, Byte.TYPE, Character.TYPE,
Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE
};
try {
for ( Class type : typesList ) {
if (type.isPrimitive()) {
System.out.println("Primitive type:\t" + type);
}
else {
boolean hasSize = false;
java.lang.reflect.Field fields[] = type.getFields();
for (int count=0; count<fields.length; count++) {
if (fields[count].getName().contains("SIZE")) hasSize = true;
}
if (hasSize) {
System.out.println("Bits size of type " + type + " :\t\t\t" + type.getField("SIZE").getInt(type) );
double value = type.getField("MIN_VALUE").getDouble(type);
long longVal = Math.round(value);
if ( (value - longVal) == 0) {
System.out.println("Min value for type " + type + " :\t\t" + longVal );
longVal = Math.round(type.getField("MAX_VALUE").getDouble(type));
System.out.println("Max value for type " + type + " :\t\t" + longVal );
}
else {
System.out.println("Min value for type " + type + " :\t\t" + value );
value = type.getField("MAX_VALUE").getDouble(type);
System.out.println("Max value for type " + type + " :\t\t" + value );
}
}
else {
System.out.println(type + "\t\t\t type without SIZE field.");
}
} // if not primitive
} // for typesList
} catch (Exception e) {e.printStackTrace();}
} // main
} // class PrimitiveTypes
Not sure for older versions, but since version 1.8 java sdk provides the .BYTES properties for boxed Objects of primitive types.
BYTES ( = SIZE / Byte.size )
import java.util.*;
import java.lang.*;
import java.io.*;
// The main method must be in a class named "Main".
class Main {
public static void main(String[] args) {
System.out.println("size of Integer: " + Integer.BYTES);
System.out.println("size of Character: " + Character.BYTES);
System.out.println("size of Short: " + Short.BYTES);
System.out.println("size of Long: " + Long.BYTES);
System.out.println("size of Double: " + Double.BYTES);
System.out.println("size of Float: " + Float.BYTES);
}
}