Primitive Types
Navigate Language Fundamentals topic: ) |
Primitive types are the most basic data types available within the Java language. There are 8: boolean
, byte
, char
, short
, int
, long
, float
and double
. These types serve as the building blocks of data manipulation in Java. Such types serve only one purpose — containing pure, simple values of a kind. Because these data types are defined into the Java type system by default, they come with a number of operations predefined. You can not define a new operation for such primitive types. In the Java type system, there are three further categories of primitives:
- Numeric primitives:
short
,int
,long
,float
anddouble
. These primitive data types hold only numeric data. Operations associated with such data types are those of simple arithmetic (addition, subtraction, etc.) or of comparisons (is greater than, is equal to, etc.) - Textual primitives:
byte
andchar
. These primitive data types hold characters (that can be Unicode alphabets or even numbers). Operations associated with such types are those of textual manipulation (comparing two words, joining characters to make words, etc.). However,byte
andchar
can also support arithmetic operations. - Boolean and null primitives:
boolean
andnull
.
All the primitive types have a fixed size. Thus, the primitive types are limited to a range of values. A smaller primitive type (byte
) can contain less values than a bigger one (long
).
Category | Types | Size (bits) | Minimum Value | Maximum Value | Precision | Example |
---|---|---|---|---|---|---|
Integer | byte
|
8 | -128 | 127 | From +127 to -128 | byte b = 65;
|
char
|
16 | 0 | 216-1 | All Unicode characters[1] | char c = 'A';
| |
short
|
16 | -215 | 215-1 | From +32,767 to -32,768 | short s = 65;
| |
int
|
32 | -231 | 231-1 | From +2,147,483,647 to -2,147,483,648 | int i = 65;
| |
long
|
64 | -263 | 263-1 | From +9,223,372,036,854,775,807 to -9,223,372,036,854,775,808 | long l = 65L;
| |
Floating-point | float
|
32 | 2-149 | (2-2-23)·2127 | From 3.402,823,5 E+38 to 1.4 E-45 | float f = 65f;
|
double
|
64 | 2-1074 | (2-2-52)·21023 | From 1.797,693,134,862,315,7 E+308 to 4.9 E-324 | double d = 65.55;
| |
Other | boolean
|
-- | -- | -- | false, true | boolean b = true;
|
void
|
-- | -- | -- | -- | -- |
Integer primitive types silently overflow:
|
|
As Java is strongly typed, you can't assign a floating point number (a number with a decimal point) to an integer variable:
Code section 3.53: Setting a floating point number as a value to an int (integer) type.
int age;
age = 10.5;
|
A primitive type should be set by an appropriate value. The primitive types can be initialized with a literal. Most of the literals are primitive type values, except String Literals, which are instance of the String
class.
Numbers in computer science
[edit | edit source]Programming may not be as trivial or boring as just crunching huge numbers any more. However, huge chunks of code written in any programming language today, let alone Java, obsessively deal with numbers, be it churning out huge prime numbers,[2] or just calculating a cost of emission from your scooter. In 1965, Gemini V space mission escaped a near-fatal accident caused by a programming error.[3] Again in 1979, a computer program overestimated the ability of five nuclear reactors to withstand earthquakes; the plants shut down temporarily.[4] There is one thing common to both these programming errors: the subject data, being computed at the time the errors occurred, was numeric. Out of past experience, Java came bundled with revised type checking for numeric data and put significant emphasis on correctly identifying different types of it. You must recognise the importance of numeric data when it comes to programming.
Numbers are stored in memory using a binary system. The memory is like a grid of cells:
Each cell can contain a binary digit (shortened to bit), that is to say, zero or one:
0
|
1
|
1
|
0
|
0
|
1
|
0
|
1
|
Actually, each cell does contain a binary digit, as one bit is roughly equivalent to 1
and an empty cell in the memory signifies 0
. A single binary digit can only hold two possible values: a zero or a one.
Memory state | Gives | ||||||||
0
|
→ | 0 | |||||||
1
|
→ | 1 |
Multiple bits held together can hold multiple permutations — 2 bits can hold 4 possible values, 3 can hold 8, and so on. For instance, the maximum number 8 bits can hold (11111111
in binary) is 255
in the decimal system. So, the numbers from 0 to 255 can fit within 8 bits.
Memory state | Gives | ||||||||
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
→ | 0 |
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
→ | 1 |
0
|
0
|
0
|
0
|
0
|
0
|
1
|
0
|
→ | 2 |
0
|
0
|
0
|
0
|
0
|
0
|
1
|
1
|
→ | 3 |
... |
... | ||||||||
1
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
→ | 255 |
It is all good, but this way, we can only host positive numbers (or unsigned integers). They are called unsigned integers. Unsigned integers are whole number values that are all positive and do not attribute to negative values. For this very reason, we would ask one of the 8 bits to hold information about the sign of the number (positive or negative). This leaves us with just 7 bits to actually count out a number. The maximum number that these 7 bits can hold (1111111
) is 127
in the decimal system.
Positive numbers
Memory state | Gives | |||||||||
0
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
→ | 0 | |
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
→ | 1 | |
0
|
0
|
0
|
0
|
0
|
0
|
1
|
0
|
→ | 2 | |
0
|
0
|
0
|
0
|
0
|
0
|
1
|
1
|
→ | 3 | |
... |
... |
... | ||||||||
0
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
→ | 127 |
Negative numbers
Memory state | Gives | |||||||||
1
|
0
|
0
|
0
|
0
|
0
|
0
|
0
|
→ | -128 | |
1
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
→ | -127 | |
1
|
0
|
0
|
0
|
0
|
0
|
1
|
0
|
→ | -126 | |
1
|
0
|
0
|
0
|
0
|
0
|
1
|
1
|
→ | -125 | |
... |
... |
... | ||||||||
1
|
1
|
1
|
1
|
1
|
1
|
1
|
1
|
→ | -1 |
Altogether, using this method, 8 bits can hold numbers ranging from -128
to 127
(including zero) — a total of 256 numbers. Not a bad pay-off one might presume. The opposite to an unsigned integer is a signed integer that have the capability of holding both positive and negative values.
But, what about larger numbers. You would need significantly more bits to hold larger numbers. That's where Java's numeric types come into play. Java has multiple numeric types — their size dependent on the number of bits that are at play.
In Java, numbers are dealt with using data types specially formulated to host numeric data. But before we dive into these types, we must first set some concepts in stone. Just like you did in high school (or even primary school), numbers in Java are placed in clearly distinct groups and systems. As you'd already know by now, number systems includes groups like the integer numbers (0, 1, 2 ... ∞); negative integers (0, -1, -2 ... -∞) or even real and rational numbers (value of Pi, ¾, 0.333~, etcetera). Java simply tends to place these numbers in two distinct groups, integers (-∞ ... 0 ... ∞) and floating point numbers (any number with decimal points or fractional representation). For the moment, we would only look into integer values as they are easier to understand and work with.
Integer types in Java
[edit | edit source]With what we have learned so far, we will identify the different types of signed integer values that can be created and manipulated in Java. Following is a table of the most basic numeric types: integers. As we have discussed earlier, the data types in Java for integers caters to both positive and negative values and hence are signed numeric types. The size in bits for a numeric type determines what its minimum and maximum value would be. If in doubt, one can always calculate these values.
Lets see how this new found knowledge of the basic integer types in Java fits into the picture. Say, you want to numerically manipulate the days in a year — all 365 days. What type would you use? Since the data type byte
only goes up to 127, would you risk giving it a value greater than its allowed maximum. Such decisions might save you from dreaded errors that might occur out of the programmed code. A much more sensible choice for such a numeric operation might be a short
. Now, why couldn't they make just one data type to hold all kinds of numbers? Let's explore why.
When you tell a program you need to use an integer, say even a byte
, the Java program allocates a space in the memory. It allocates whole 8 bits of memory. Where it wouldn't seem to matter for today's memory modules that have place for almost a dozen trillion such bits, it matters in other cases. Once allocated that part of the memory gets used and can only be claimed back after the operation is finished. Consider a complicated Java program where the only data type you'd be using would be long
integers. What happens when there's no space for more memory allocation jobs? Ever heard of the Stack Overflow errors. That's exactly what happens — your memory gets completely used up and fast. So, choose your data types with extreme caution.
Enough talk, let's see how you can create a numeric type. A numeric type begins with the type's name (short
, int
, etc.) and then provides with a name for the allocated space in the memory. Following is how it's done. Say, we need to create a variable to hold the number of days in a year.
Code section 3.54: Days in a year.
short daysInYear = 365;
|
Here, daysInYear
is the name of the variable that holds 365
as its value, while short
is the data type for that particular value. Other uses of integer data types in Java might see you write code such as this given below:
Code section 3.55: Integer data types in Java.
byte maxByte = 127;
short maxShort = 32767;
int maxInt = 2147483647;
long maxLong = 9223372036854775807L;
|
Integer numbers and floating point numbers
[edit | edit source]The data types that one can use for integer numbers are byte
, short
, int
and long
but when it comes to floating point numbers, we use float
or double
. Now that we know that, we can modify the code in the code section 3.53 as:
Code section 3.56: Correct floating point declaration and assignment.
double age = 10.5;
|
Why not float
, you say? If we'd used a float
, we would have to append the number with a f
as a suffix, so 10.5
should be 10.5f
as in:
Code section 3.57: The correct way to define floating point numbers of type float .
float age = 10.5f;
|
Floating-point math never throws exceptions. Dividing a non-zero value by 0
equals infinity
. Dividing a non-infinite value by infinity
equals 0
.
Question 3.7: Consider the following code:
Question 3.7: Primitive type assignments.
...
a = false;
b = 3.2;
c = 35;
d = -93485L;
e = 'q';
|
These are five variables. There are a long
, a byte
, a char
, a double
and a boolean
. Retrieve the type of each one.
Answer 3.7: Primitive type assignments and declarations.
boolean a;
double b;
byte c;
long d;
char e;
a = false;
b = 3.2;
c = 35;
d = -93485L;
e = 'q';
|
a
can only be theboolean
because only a boolean can handle boolean values.e
can only be thechar
because only a char can contain a character.b
can only be thedouble
because only a double can contain a decimal number here.d
is thelong
because abyte
can not contain such a low value.c
is the remaining one so it is thebyte
.
Data conversion (casting)
[edit | edit source]Data conversion (casting) can happen between two primitive types. There are two kinds of casting:
- Implicit: casting operation is not required; the magnitude of the numeric value is always preserved. However, precision may be lost when converting from integer to floating point types
- Explicit: casting operation required; the magnitude of the numeric value may not be preserved
Code section 3.58: Implicit casting (int is converted to long, casting is not needed).
int i = 65;
long l = i;
|
Code section 3.59: Explicit casting (long is converted to int, casting is needed).
long l = 656666L;
int i = (int) l;
|
The following table shows the conversions between primitive types, it shows the casting operation for explicit conversions:
from byte
|
from char
|
from short
|
from int
|
from long
|
from float
|
from double
|
from boolean
| |
---|---|---|---|---|---|---|---|---|
to byte
|
- | (byte) | (byte) | (byte) | (byte) | (byte) | (byte) | N/A |
to char
|
- | (char) | (char) | (char) | (char) | (char) | N/A | |
to short
|
(short) | - | (short) | (short) | (short) | (short) | N/A | |
to int
|
- | (int) | (int) | (int) | N/A | |||
to long
|
- | (long) | (long) | N/A | ||||
to float
|
- | (float) | N/A | |||||
to double
|
- | N/A | ||||||
to boolean
|
N/A | N/A | N/A | N/A | N/A | N/A | N/A | - |
Unlike C, C++ and similar languages, Java can't represent false
as 0
or null
and can't represent true
as non-zero. Java can't cast from boolean to a non-boolean primitive data type, or vice versa.
For non primitive types:
to Integer | to Float | to Double | to String | to Array | |
---|---|---|---|---|---|
Integer | - | (float)x | (double)x x.doubleValue() |
x.toString() Float.toString(x) |
new int[] {x} |
Float | java.text.DecimalFormat("#").format(x) | - | (double)x | x.toString() | new float[] {x} |
Double | java.text.DecimalFormat("#").format(x) | java.text.DecimalFormat("#").format(x) | - | x.toString() | new double[] {x} |
String | Integer.parseInt(x) | Float.parseFloat(x) | Double.parseDouble(x) | - | new String[] {x} |
Array | x[0] | x[0] | x[0] | Arrays.toString(x) | - |
Notes
[edit | edit source]- ↑ According to "STR01-J. Do not assume that a Java char fully represents a Unicode code point". Carnegie Mellon University - Software Engineering Institute. Retrieved 27 Nov 2018., not all Unicode characters fit into a 16 bit representation
- ↑ As of edit (11 December 2013), the Great Internet Mersenne Prime Search project has so far identified the largest prime number as being 17,425,170 digits long. Prime numbers are valuable to cryptologists as the bigger the number, the securer they can make their data encryption logic using that particular number.
- ↑ Gemini 5 landed 130 kilometers short of its planned Pacific Ocean landing point due to a software error. The Earth's rotation rate had been programmed as one revolution per solar day instead of the correct value, one revolution per sidereal day.
- ↑ A program used in their design used an arithmetic sum of variables when it should have used the sum of their absolute values. (Evars Witt, "The Little Computer and the Big Problem", AP Newswire, 16 March 1979. See also Peter Neumann, "An Editorial on Software Correctness and the Social Process" Software Engineering Notes, Volume 4(2), April 1979, page 3)