Data Types in Java
A computer language’s type system specifies how data elements—variables and constants—are connected to memory storage and each other. The type of a data element in a statically typed language, like C or C++, is a straightforward, constant property that frequently correlates directly to some underlying hardware phenomenon, like a register or a pointer value. Read more to know about Data types in java and types of data types.
In more dynamic languages like Smalltalk or Lisp, variables can be given arbitrary elements and effectively change their type throughout their lifespan. Validating what occurs in these languages at runtime involves a significant overhead.
Perl and other scripting languages make things simple to use by offering significantly reduced type systems, where values are consolidated into a common representation, like strings, and only specific data pieces can be kept in variables.
Java combines the most significant aspects of statically and dynamically typed languages. It is a statically typed language, meaning all variables and programming elements have a type known at compile time.
This feature eliminates the need for the runtime system to verify that type assignments are valid while the code runs. In contrast to conventional C or C++, Java preserves object runtime information and uses it to enable genuinely dynamic behavior.
Casting and full polymorphism (extending of types) are made possible by Java code’s ability to load new types at runtime and use them in entirely object-oriented ways.
Java data comes in two types. Primitive types are fixed elements, like literal constants and numerals, representing fundamental values with built-in language capabilities.
Objects and arrays are examples of reference types (also known as class types) because they “refer to” a vast data type that is passed “by reference.”
Primitive Types
In Java, letters, numbers, and Boolean values are essential components. Unlike several other (perhaps more pure) object-oriented languages, they are not objects.
Java has “wrapper” classes for circumstances where treating a primitive value as an object is preferable.
Treating primitive values as unique has the main benefit of making it easier for the Java compiler and runtime to optimize their implementation.
Lower-level languages have always allowed for mapping primitive values and computations to hardware.
Type | Definition |
boolean | true or false |
char | 16-bit Unicode character |
byte | 8-bit, signed, two’s complement integer |
short | 16-bit, signed, two’s complement integer |
int | 32-bit, signed, two’s complement integer |
long | 64-bit, signed, two’s complement integer |
float | 32-bit, IEEE 754, floating-point value |
Floating-point precision
Because Java’s floating-point operations adhere to the IEEE 754 international specification, floating-point computations often yield identical results across Java platforms. However, this is only applicable to platforms that support it.
Java has enabled more precision since Version 1.3. These factors can cause incredibly subtle and obscure variations in the outcomes of high-precision processes.
Although most applications would never notice this, you can use the special keyword strictfp as a class modifier on the class containing the floating-point manipulation to ensure that your application generates the same results on different platforms. The compiler then forbids platform-specific optimizations.
Variable declaration and initialization
In C style, variables are defined inside methods or classes, with one or more variable names separated by commas after the type.
int foo;
double d1, d2;
boolean isFun;
When variables are declared, it is optional to initialize them with a suitable expression:
int foo = 42;
double d1 = 3.14, d2 = 2 * 3.14;
boolean isFun = true;
If variables designated as class members are not initialized, they are set to their default values. In this instance, characters are assigned to the null character (\0), Boolean variables have the value false, and numeric types default to the proper flavor of zero.
On the other hand, local variables need to be explicitly initialized before they can be used. These variables are declared inside a method and only exist during a method call.
Integer literals
Integer literals can be specified in octal (base 8), decimal (base 10), or hexadecimal (base 16). A decimal integer is specified by a sequence of digits beginning with one of the characters 1-9:
int i = 1320;
Octal numbers are distinguished from decimal numbers by a leading zero:
int i = 01320; // i = 664 decimal
A hexadecimal number is denoted by the leading characters 0x or 0X (zero “x”), followed by a combination of digits and the characters a-f or A-F, which represent the decimal values 10-15:
int i = 0xFFFF; // i = 65535 decimal
Integer literals are of type int unless they are suffixed with an L, denoting that they are to be produced as a long value:
long l = 14L;
long l = 14; // equivalent: 14 is converted from type int
When a numeric type is used in an assignment or an expression involving a “larger” type with a more excellent range, it can be promoted to the more prominent type.
In the second line of the previous example, the number 14 has the default type of int, but it’s promoted to type long for assignment to the long variable.
Certain other numeric and comparison operations also cause this kind of arithmetic promotion, as do mathematical expressions involving more than one type.
For example, when multiplying a byte value by an int value, the compiler promotes the byte to an int first:
byte b = 32;
int i = 33;
int result = b * i; // b is promoted to int before multiplication
However, without an explicit cast, you can never assign a numeric value to a type with a smaller range.
int i = 23;
byte b = i; // Compile-time error, explicit cast needed
byte b = (byte) i; // OK
Conversions from floating-point to integer types always require an explicit cast because of the potential loss of precision.
Floating-point literals
Decimal or scientific notation can be used to specify floating-point quantities. Unless they are followed by a f or F to indicate that they are to be generated as a float value, floating-point literals are of type double.
double d = 9.21;
double e = 5.00e+8;
float f = 1.21F;
float g = 4.00e+8F;
Floating-point literals
Decimal or scientific notation can be used to specify floating-point quantities. Unless they are followed by a f or F to indicate that they are to be generated as a float value, floating-point literals are of type double.
double d = 9.21;
double e = 5.00e+8;
float f = 1.21F;
float g = 4.00e+8F;
Character literals
Either a single-quoted character or an escaped ASCII or Unicode sequence can be used to specify a literal character value:
char b = 'b';
char newline = '\n';
char smiley = '\u263a';
References Types
In an object-oriented language like Java, a class is created from simple primitives to generate new, complicated data types. After that, every class functions as a new type in the language.
A new type named Foo is implicitly created in Java when a new class called Foo is created. Where an item can be assigned and how it is used depends on its kind.
Similar to primitives, an object of type Foo can typically be supplied as an argument to a method that takes a Foo value or is assigned to a variable of type Foo.
A type is more than just an attribute. Both classes and the types they represent can have relationships with one another. A child class or subclass is a specialized form of its parent class; all classes are part of a parent-child hierarchy.
The relationship between the respective types is the same, with the child class’s type being regarded as a subtype of the parent class.
An object of the child’s type is an extension of or equivalent to the parent type since child classes inherit all of the functionality of their parent classes.
It is possible to substitute an item of the child type for an object of the parent type. For instance, the new type of Cat is regarded as a subtype of Animal if it is created as a new class that extends Animal.
When an object of type Cat is assignable to a variable of type Animal, it can be used anywhere an object of type Animal can be used. One of the main characteristics of an object-oriented language is subtype polymorphism.
Java uses primitive types that are provided “by value.” Put otherwise, a primitive value, such as an int, is copied when given to a variable or passed as an argument to a method.
In contrast, we always access reference types “by reference.” A reference is only an object’s name or handle. A “pointer” to an object of its kind is what a reference type variable has. Only the reference—not the item it points to—is copied when assigned or supplied to a method.
Similar to a pointer in C or C++, a reference is an atomic entity whose type is so tightly enforced that it cannot be altered. It is impossible to create or modify the reference value itself. The only way to give a variable a reference value is to assign it to the correct object.
Classes always define objects, and types of references always point to objects. Arrays and interfaces, two different types of reference types, specify the kind of object they point to in slightly different ways.
In Java, arrays hold a unique position within the type system. They are a unique sort of object automatically generated to include a collection of base types, which are other types of objects.
Interfaces are a little more cunning. An interface assigns a corresponding type and defines a collection of methods.
An object can be considered of that type if it implements every interface method. Class types, variables, and method parameters can be declared interface types and assigned to any object that implements the interface.
Because of this, Java can effectively create objects with multiple types, bridging the gap between the class hierarchy. Interfaces will also be discussed in the upcoming chapter.
The Java class syntax is extended with generic types, often known as parameterized types. These types provide more abstraction in how classes interact with other Java types. Generics enable the user to specialize in classes without altering any of the original class’s code.