Primitive types are the most basic data types available within the Java language. There are 8 primitive data types: 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.

Data types are divided into two groups:

  • Primitive data types - includes byte, short, int, long, float, double, boolean and char
  • Non-primitive(Derived) data types - such as String, Arrays and Classes 
Data Type Size Description
byte 1 byte Stores whole numbers from -128 to 127
short 2 bytes Stores whole numbers from -32,768 to 32,767
int 4 bytes Stores whole numbers from -2,147,483,648 to 2,147,483,647
long 8 bytes Stores whole numbers from -9,223,372,036,854,775,808 to
float 4 bytes Stores fractional numbers from 3.4e-038 to 3.4e+038. Sufficient for
storing 6 to 7 decimal digits
double 8 bytes Stores fractional numbers from 1.7e-308 to 1.7e+038. Sufficient for
storing 15 decimal digits
boolean 1 byte Stores true or false values
char 2 bytes Stores a single character/letter

User Defined Data Types

User defined data types are those that user / programmer himself defines. For example, classes, interfaces. For example:

Here obj is a variable of data type MyClass and we call them reference variables as they can be used to store the reference to the object of that class.

Declaration of Variables and Assignment

In Java, variables are the names of storage locations. After designing suitable variable
names, we must declare them to the compiler. Declaration does three things:

  1. It tells the compiler what the variable name is.
  2. It specifies what type of data the variable will hold.
  3. The place of declaration (in the program) decides the scope of the variable.

A variable can be used to store a value of any data type. That is, the name has nothing to do with the type. Java allows any properly formed variable to have any declared data type. The general form of declaration of a variable is:
                                type variable1, variable2,…………………………., variable 

A simple method of giving value to a variable is through the assignment statement as follows:
                           variableName = value;
For Example:
abc = 100;
XYZ = 10.2;
It is also possible to assign a value to a variable at the time of its declaration. This takes the form: 

Type Conversion and Casting

Conversion of one data type to another data type is called type casting. If the two types are compatible, then Java will perform the conversion automatically. For example, it is always possible to assign an int value to a long variable. However, not all types are compatible, and thus, not all type conversions are implicitly allowed. For instance, there is no automatic conversion defined from double to byte. Fortunately, it is still possible to obtain a conversion between incompatible types.

To do so, you must use a cast, which performs an explicit conversion between incompatible types. 

Java’s Automatic Conversions

When one type of data is assigned to another type of variable, an automatic type conversion will take place if the following two conditions are met:

  • The two types are compatible.
  • The destination type is larger than the source type.

When these two conditions are met, a widening conversion takes place. For example, the int type is always large enough to hold all valid byte values, so no explicit cast statement is required. For widening conversions, the numeric types, including integer and floating-point types, are compatible with each other.

However, there are no automatic conversions from the numeric types to char or boolean. Also, char and boolean are not compatible with each other. As mentioned earlier, Java also performs an automatic type conversion when storing a literal integer constant into variables of type byte, short, long, or char. 

Casting Incompatible Types

Although the automatic type conversions are helpful, they will not fulfill all needs. For example, what if you want to assign an int value to a byte variable? This conversion will not be performed automatically, because a byte is smaller than an int. This kind of conversion is sometimes called a narrowing conversion, since you are explicitly making the value narrower so that it will fit into the target type.

To create a conversion between two incompatible types, you must use a cast. A cast is simply an explicit type conversion. It has this general form:
                                                (target-type) value
Here, target-type specifies the desired type to convert the specified value to. For example, the following fragment casts an int to a byte. If the integer’s value is larger than the range of a byte, it will be reduced modulo (the remainder of an integer division by the) byte’s range.
int a;
byte b;
// ... b = (byte) a; 

 The following program demonstrates some type conversions that require casts: 

Let’s look at each conversion. When the value 257 is cast into a byte variable, the result is the remainder of the division of 257 by 256 (the range of a byte), which is 1 in this case. When the d is converted to an int, its fractional component is lost. When d is converted to a byte, its fractional component is lost, and the value is reduced modulo 256, which in this case is 67. 

Garbage Collection

Java garbage collection is the process by which Java programs perform automatic memory management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM for short. When Java programs run on the JVM, objects are created on the heap, which is a portion of memory dedicated to the program. Eventually, some objects will no longer be needed. The garbage collector finds these unused objects and deletes them to free up memory.

In C/C++, programmer is responsible for both creation and destruction of objects. Usually programmer neglects destruction of useless objects. Due to this negligence, at certain point, for creation of new objects, sufficient memory may not be available and entire program will terminate abnormally causing OutOfMemoryErrors.

But in Java, the programmer need not to care for all those objects which are no longer in use. Garbage collector destroys these objects. Main objective of Garbage Collector is to free heap memory by destroying unreachable objects. Generally, an object becomes eligible for garbage collection in Java on following cases:

  1. All references to that object explicitly set to null e.g. object = null
  2. The object is created inside a block and reference goes out scope once control exit that block.
  3. Parent object set to null if an object holds the reference to another object and when you set container object's reference null, child or contained object automatically becomes eligible for garbage collection.