Learn about Java data types. Difference between primitive datatype and non-primitive datatype (or reference datatype). Know data types sizes and best practices to use datatypes in Java.
1. What is Data Type
In Java, typically data-types are associated with variables. A variable has three properties:
- A variable name (also called identifier) to refer to the memory location
- The type of the data stored at the memory location (it is called datatype)
- A memory location to hold the value
The second property (marked in red) is called data type. The data type of the variable determines the range of the values that the memory location can hold. Therefore, the amount of memory allocated for a variable depends on its data type. For example, 32 bits of memory is allocated for a variable of the
'int' data type.
Java is a statically-typed language. This means all variables MUST be declared before they can be used.
boolean flag = true; int counter = 20;
2. Types of data type in Java
Java supports two kinds of data types i.e. primitive data type and non-primitive or reference data type.
2.1. Primitive Data Types
A primitive data type directly holds a value in memory. For instance, a number or a character. Primitive data types are
not objects, as well as not references to objects.
The values stored in primitives are called literals. A literal is the source code representation of a fixed value; literals are represented directly in your code without requiring computation.
In Java, we have 8 types of primitive data types.
|Data Type||Description||Default Value||Memory Size|
|A binary value of either ||1 bit|
|Any unicode character||\u0000 (0)||16 bit unicode character|
|values values from -128 to 127||0||8 bit signed value|
|values values from -32768 to 32767||0||16 bits signed value|
|values values from from -231 to 231-1||0||32 bits signed value|
|values values from from -263 to 263-1||0||64 bit floating point value|
|IEEE 754 floating point||0.0||32 bit floating point value|
|IEEE 754 floating point||0.0||64 bit floating point value|
In Java SE 7 and later, any number of underscore characters (
'_') can appear anywhere between digits in a numerical literal. e.g.
10_000_000is a valid number in Java.
2.1.1.Type conversion between primitives
With the exception of
boolean, you can assign a primitive value to another primitive type. Though, sometimes it may result in data loss when a primitive of large memory capacity is assigned to primitive with smaller memory capacity. It’s just like you are transferring the water from a large vessel and putting in smaller vessel, so loss of water is natural.
int counter = 20_000_000; //Assign int to short (data loss) short shortCounter = (short) counter; //assign int to long (no data loss) long longCounter = counter; System.out.println(counter); //20000000 System.out.println(shortCounter); //11520 System.out.println(longCounter); //20000000
Notice that when Java detects that type conversion may result in data loss (bigger data type to smaller one), then gives type-mismatch error and explicitly asks for type casting (e.g. ‘int’ to ‘short’ assignment). It helps in detecting and resolving accidental data loss assignments.
2.2. Non-primitive Data Types
A non-primitive or reference data type holds the reference to an object in memory. Using the reference stored in the variable you can access fields and methods of the referenced object.
java.lang.String is a class defined in the Java library and you can use it to manipulate text (sequence of characters). You declare a reference variable of type
String str = new String( "Hello World !!" );
What happens when this code is executed? First, a memory block is allocated and the name of the variable
str is associated with that memory location. This process is the same as declaring a primitive data type variable.
The second part of code creates a new
String object in memory with text
"Hi" and stores the reference (or memory address) of the
String object into the variable
2.2.1. Multiple references can refer to same object
You can also assign the reference of an object stored in one reference variable to another reference variable. In such cases, both reference variables will refer to the same object in memory.
// Declares String reference variable str1 and str2 String str1; String str2; // Assigns the reference of a String object "Hello" to str1 str1 = new String( "Hello World !!" ); // Assigns the reference stored in str1 to str2 str2 = str1; System.out.println( str1 ); //Hello World !! System.out.println( str2 ); //Hello World !!
nullis assigned to a reference variable, it means that the reference variable is not referring to any object in memory.
2.2.2. Wrapper Classes
A Wrapper class is a class whose object wraps or contains a primitive data types. In other words, we can wrap a primitive value into a wrapper class object.
Please note that Java has one wrapper class mapped to each primitive data type. For example,
java.lang.Integer class is object version of
int data type. Similarly, we have total 8 wrapper classes for all 8 primitive data types.
The wrapper class names are same as primitive data types names, only starting with a capital letter.
These wrapper classes are
2.2.3. Auto Boxing
In Java, you can assign a primitive type value to a wrapper class, directly. For example, you can assign a int value to Interger class reference.
Integer counter = 20; static Float PI = 3.14f;
It’s worth mentioning that all wrapper class instances are immutable. They also maintain an internal cache for performance reason.
3. Difference between primitive and non-primitive data types
- Primitives store values directly, which are called literals. Reference types store references to actual objects in memory area.
- There are 8 fixed primitive data types. In Java, each class is a data type including wrapper classes.
4. Best practices
- Use Java variable naming conventions and follow best practices.
- Use primitives for variables which are local in scope. e.g. inside methods, counter for loops and intermediate results.
- When data is transferred among method or classes, it’s better to use objects because only their references will be copied, no memory overhead will be added.
- When dealing with collections (which need objects), you shall be using Objects.
- While sending data over network, use objects and make them Serializable. Wrapper classes are automatically Serializable.
- Always know the size of data type you will need. Use appropriate data sizes. Using
booleanvalues (0 and 1) is waste of memory.
- Use underscores (above Java 7) in numbers. It make them more readable.
Happy Learning !!