1. Introduction
In mathematics, adding two positive numbers can only lead to a positive result. However, this addition can sometimes produce a negative result for a computer, depending on the data types involved. It’s important to master the primitive types of the Java language to avoid such situations, which can lead to disaster. In this article, you’ll learn the basics of primitive data types in Java.
2. Integer Data Types
Java has 4 primitive types for holding integers: byte, short, int, and long. These types differ in the size of the data they can contain.
byte
The byte
type allows 8-bit signed integers to be stored. One bit is used for the sign, 7 bits remain for the number. Which therefore makes $2^7$ possible values. The minimum value is -128 ($-2^7$) and the maximum is 127($2^7 – 1$).
You can declare your byte variable by using the following syntax:
byte myByte = 10;
short
The byte
type is no longer indicated for integers greater than 127 in absolute value. The short
type will therefore allow 16-bit signed integers to be stored. The short
type allows you to store integers between $-2^{15}$ and $2^{15} -1$.
Just like the byte variable, you might declare a short like this:
short myShort = 150;
int
The int
type is the one that is used most of the time for arithmetic operations on integers. It is indicated for 32-bit signed integers. The minimum limit is therefore $-2^{31}$ and the maximum limit is $2^{31} – 1$. Since Java 8, the Integer class provides a set of static methods for handling unsigned integers. These include methods such as: toUnsignedString()
, compareUnsigned()
.
Here is how you declare an int variable in Java:
int myInt = 33000;
long
The long
type is indicated for arithmetic operations on large integers. It allows you to store signed integers on 64 bits. It allows you to store integers between $-2^{63}$ and $2^{63} – 1$. Just like for the int
type, Java has introduced a set of static methods in the Long class for manipulating unsigned integers.
Add the Suffix “l” or “L” to an integer literal to turn it into a long.
long myLong = 2147483648L;
long myOtherLong = 2147483649l;
3. Floating-Point Data Types
For handling decimal numbers, Java offers two primitive data types: float and double.
float
The float
type allows you to handle single-precision floating-point decimal numbers. You declare a float literal by appending an “f” or “F” at the end of the number.
Find below three different ways of declaring the same float literal.
float myFloat1 =2f;
float myFloat2 =2F;
float myFloat3 =2e0f;//Scientific notation
double
To store double-precision decimals, you must use the double
type. This is also the type that is used by default for decimal numbers.
You can also add the suffixes “d” and “D” at the end of a number to indicate that it is a “double”.
double myDouble1 = 23.12;
double myDouble2 = 23.12d;
double myDouble3 = 23.12D;
double myDouble4 = 23.12e0;//Scientific notation
4. The char Data Type
This data type represents a single 16-bit Unicode character. Java stores characters as unsigned integers with values ranging from 0 to $2^{16} -1$.
You can create characters in Java in the following ways :
The Single quote
char myChar = 'a';
Using the Unicode escape
char myChar = '\u0061'; //0061 is the hexadecimal Unicode Code of 'a'
With the Unicode decimal values
char myChar = 97; //97 is the Unicode decimal Code of 'a'
You can find the full list of Unicode characters here.
Do not confuse a string declared with double quotes with a character that uses single quotes.
char myChar = 'b';
String myString = "b";//This is a String not a char
You will learn more about the String class later.
5. The boolean Data Type
This data type is used to store variables that can only take two possible values: true
or false
.
This is how you declare a boolean
variable :
boolean myBoolean = false;
boolean myOtherBoolean = true;
6. Summary of Primitive Data Types
Data Type | Size(bit) | Default Value | Minimum Value | Maximum Value |
---|---|---|---|---|
byte | 8 | 0 | $-2^{7}$ | $2^{7} – 1$ |
short | 16 | 0 | $-2^{16}$ | $2^{16} – 1$ |
int | 32 | 0 | $-2^{32}$ | $2^{32} – 1$ |
long | 64 | 0L | $-2^{64}$ | $2^{64} – 1$ |
float | 32 | 0.0F | 1.4E-45 | 3.4028235E38 |
double | 64 | 0.0D | 4.9E-324 | 1.7976931348623157E308 |
char | 16 | 0 or ‘\u0000’ | 0 | $2^{16} – 1$ or ‘\uffff’ |
boolean | NA | false | false | true |
7. Practical Tips
Use the right Data type to Save memory
Memory management will not be a major concern in most of your programs. However, in some cases, it can be useful to make the right choices to optimize memory usage. For example, suppose you have to manipulate a very large array containing integers. If you know that the values in your array will never be beyond 100 for example, it is better to use the byte
type.
The array below is using around 4 Gbytes of memory.
int[] myLargeArray = new int[1_000_000_000];// each integer uses 4 bytes
Changing from int
to byte
and you will divide the memory size by 4.
byte[] myLargeArray = new byte[1_000_000_000];
Use Capital L for long
literals
To make your programs easier to read, use an uppercase “L” rather than a lowercase “l” to declare long
types. People can easily confuse the lowercase ‘l’ with the number ‘1’.
How would you represent the number 100 as a long?
long oneHundred = 100l;
As you can see, this looks like 1001 (One thousand and one). To avoid this, the recommendation is to prefer the capital “L” to create a long literal.
long oneHundred = 100L;
Avoid Overflow
All primitive types have limits. Any attempt to exceed it will produce an erroneous result.
int myIntValue = Integer.MAX_VALUE; //2147483647
int myOtherIntValue = Integer.MIN_VALUE; //-2147483648
if(myIntValue + 1 == myOtherIntValue){
System.out.println("Adding 1 to the Max value leads to an overflow");
}
Running this code fragment will display “Adding 1 to the Max value leads to an overflow” on the screen. As you can see, adding 1 to a positive value gives you a negative value. Which mathematically makes no sense.
Using Underscore (_) to improve readability
You can use the underscore in your numbers to make it easier to read.
int myIntValue = 1_574_641_000;
long myLongValue = 5_531_563_452L;
float myFloatValue = 3.14_159_265_358F;
double myDoubleValue = 3.14_159_265_358D;
Be careful though, because you cannot place the underscore everywhere. You cannot place it at the following locations :
- At the beginning or end of a number
- Adjacent to a decimal point in a floating point literal
- Before an F or L suffix
- In positions where the compiler expects a string of digits
8. Conclusion
In this article, you learned about the different primitive data types that exist in Java. For numeric types, you saw the minimum and maximum values for each type. You also saw some practical tips to include in your day-to-day coding journey to enhance the quality of your Java programs.
In the next article, you’ll see the different operators you can apply to these primitive types.
9. References
1) OCP Oracle Certified Professional Java SE 17 by Khalil A. Mughal and Vasily A. Strelnikov
2) Oracle Java Documentation
Pingback: How to Fix NullPointerException In Java
Pingback: BigDecimal Class In Java