Types in Java
In Java, data can be categorized into two fundamental types: objects and primitives. Every data member and local variable in Java must be associated with a data type, which can either be a primitive or an object (class type). A primitive data type is designed to store a single item of data efficiently, utilizing a small amount of memory. On the other hand, an object represents a significant block of memory capable of holding a substantial amount of data, alongside methods for processing that data.
Primitives offer a compact representation for simple data values, such as integers, characters, or booleans. They are optimized for memory usage and provide direct access to the value they hold. Objects, in contrast, provide a more comprehensive structure that includes not only the data itself but also the methods or operations that can be performed on that data.
Primitives Data Types
The language specification defines a set of eight primitive data types. These include byte, short, int, long, float, double, char, and boolean. These specific types are the only primitive data types that can be used in a Java program. It is not possible to define additional primitive data types beyond these predefined ones.
The reason for having primitive data types is rooted in performance considerations. Since primitives are utilized extensively in Java programs, representing them as objects would introduce significant overhead and lead to a noticeable degradation in performance. By keeping them as primitives, Java ensures efficient memory usage and allows for direct manipulation of these fundamental data values. The primitive data types are following:
The boolean primitive data type in Java possesses two distinct values: true and false. It is important to note that both of these values are represented in lowercase. The boolean type is primarily employed for logical operations, often utilized to ascertain the truth or falsity of a particular condition.
By utilizing boolean variables, programmers can evaluate and control the flow of their programs based on specific conditions. The true value signifies that a condition is met or valid, while the false value indicates the opposite. The boolean type is frequently employed in conditional statements, loops, and decision-making processes to determine the execution path of a program.
Java evaluates a boolean expression by first evaluating the expression on the left, then evaluating the expression on the right, and finally applying the relational operator to determine whether the entire expression evaluates to true or false.
The smallest of the integral data types is the byte. It has a minimum value of -128 and a maximum value of 127 . The default value for byte data type is zero -'0'.
The char data type in Java is designed to represent sixteen-bit Unicode characters, providing support for a vast range of characters from various character sets used in languages worldwide. Unicode encompasses an extensive collection of characters, enabling developers to work with diverse linguistic symbols and scripts.
In Java, the char data type is denoted by a pair of single quotation marks, enclosing a single character. Additionally, when a character is represented using its Unicode value, the syntax '\u' is used followed by the corresponding hex code. This notation clarifies that the character is being represented in Unicode.
The char data type has a minimum value of '\u0000', which is equivalent to 0, and a maximum value of '\uffff'. It is important to note that unlike in the C programming language, Java does not support signed characters. The designers of Java deliberately opted against supporting signed characters and unsigned numbers due to their potential to introduce bugs into programs.
In addition, Java supports a number of other escape characters that make it easy both to represent commonly used nonprinting ASCII characters such as newline and to escape certain punctuation characters that have special meaning in Java. For example:
char backspace = '\b';
char tab = '\t';
A short is sixteen bits long. It has a minimum value of -32,768 and a maximum value of 32,767 . Because a short is signed, and a char is not signed, a char is numerically larger than a short, so you cannot assign a char to a short. default value for short is zero -'0'.
short i = 12000;
The int data type in Java represents a four-byte number, consisting of thirty-two bits. It has the capacity to represent a total of 4,294,967,296 distinct numbers. To ensure platform-neutrality, Java maintains consistency by always making an int occupy 32 bits in every Java Virtual Machine (JVM). Similarly, other data types such as short always occupy 16 bits, and long always occupy 64 bits.
This approach saves Java from the challenges faced by programmers using the 'C' programming language when porting their code across different platforms. In 'C', the size of int can vary, leading to potential compatibility issues. For instance, an int in a 'C' program can be two bytes on one operating system and four bytes on another. In contrast, Java's fixed specifications for data types provide a reliable and consistent environment for cross-platform compatibility.
Java allows for casting the int data type into other numeric types, such as byte, short, long, float, and double. However, it is crucial to note that when performing lossy casts, such as converting an int to a byte, the conversion is done modulo the length of the smaller type. This means that the value may be truncated or wrapped around to fit within the range of the target type.
A long is sixty-four bits long—eight bytes. The range of a long is quite large. This makes it useful when big, whole numbers are needed. Use this data type when you need a range of values wider than those provided by int.
The float data type in Java is employed to represent numbers with decimal values. It consists of 32 bits, adhering to the IEEE 754 floating-point standard. The float type allows for a wide range of values, enabling precise representation of decimal numbers.
Similar to other numeric types in Java, floats can be cast into other numeric types such as byte, short, long, int, and double. It is important to note that when performing lossy casts to integer types (e.g., float to short), the fractional part of the float is truncated, and the conversion is executed modulo the length of the smaller type. This means that the fractional portion is discarded, and the resulting value fits within the range of the target integer type.
The float data type provides a balance between precision and storage efficiency. It is suitable for scenarios where decimal values need to be represented with a reasonable level of accuracy while optimizing memory usage. However, it is worth noting that if higher precision is required, the double data type, which uses 64 bits, is typically preferred.
The double data type in Java is twice the size of a float, comprising 64 bits in accordance with the IEEE 754 floating-point standard. It provides increased precision compared to floats, making it suitable for scenarios where higher accuracy is required in representing decimal values.
Both floats and doubles in Java support the usage of exponential notation, allowing for concise representation of very large or very small numbers. Doubles, being 64-bit, comply with the IEEE 754 specification, ensuring consistent behavior across different platforms and conforming to standard floating-point operations.
However, it is important to consider the performance implications when choosing between a float and a double. Since most systems can only emulate 64-bit operations, using a double unnecessarily may result in a significant performance hit. If the precision offered by a float is sufficient for the intended calculations, it is advisable to opt for a float to avoid unnecessary overhead.
The default value for a double variable in Java is 0.0, indicating that if not explicitly initialized, a double variable will hold this default value.
Note: All the numeric primitive data types in Java are signed, meaning they can represent both positive and negative values. When it comes to converting or assigning a value from a larger primitive type to a smaller primitive type, casting is required.
Casting involves explicitly specifying the target data type in parentheses before the value to be converted. This tells the Java compiler to perform the conversion, even if there is a potential loss of data or precision. For example, when assigning a long value to an int variable, a cast is necessary to inform the compiler that the long value should be truncated to fit within the range of the int data type.
In a future lesson, you can investigate into type casting in greater detail. This topic will cover different types of casting, such as widening and narrowing conversions, and provide insights into handling potential data loss and choosing the appropriate casting methods.