Logo

Learning Java

Start Date: 28-Mar-2020
End Date: 27-April-2020(expected)


Primitive Data Types

The Java programming language is statically-typed, which means that all variables must first be declared before they can be used. This involves stating the variable's type and name, as

int myNumber = 1;

Doing so tells our program that a field named "myNumber" exists, holds numerical data, and has an initial value of "1".

A variable's data type determines the values it may contain, plus the operations that may be performed on it. In addition to int, the Java programming language supports seven other primitive data types.

A primitive type is predefined by the language and is named by a reserved keyword. Primitive values do not share state with other primitive values. The eight primitive data types supported by the Java programming language are:

  1. byte
  2. short
  3. int
  4. long
  5. float
  6. double
  7. boolean
  8. char

Size of Primitive Data Types and Width

A byte occupies 8 bits. A bit is not directly represented in a primitive type - We have a boolean which is not really the same thing. So a byte occupies 8 bits. We say that byte has a width of 8.

A short can store a large number and occupies 16 bits, and has a width of 16.

An int has a much larger range as we know and occupies 32 bits, and has a width of 32.

The point here is that each primitive type occupies a different amount of memory - we can see that int needs four times the amount of space , than a byte does here.


Further explained...

Category Types Size(bits) Min Value Max Value Precision
Integer
byte 8 -128 127 from +127 to -128
char 16 0 216-1 All Unicode characters
short 16 -215 215-1 From +32,767 to -32,768
int 32 -231 231-1 From +2,147,483,647 to -2,147,483,648
long 64 -263 263-1 From +9,223,372,036,854,775,807 to -9,223,372,036,854,775,808
Floating Point
float 32 2-149 (2-2-23).2127 From 3.402,823,5 E+38 to 1.4 E-45
double 64 2-1074 (2-2-52).21023 From 1.797,693,134,862,315,7 E+308 to 4.9 E-324
Other
Boolean -- -- -- false, true
Void -- -- -- --

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. We can not define a new operation for such primitive types. In the Java type system, there are three further categories of primitives:

  1. Numeric primitives: short, int, long, float and double. These primitive data types, hold only numeric data or simple arithmetic operations

  2. Textual primitives: byte and char. 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 and char can also support arithmetic operations.

  3. Boolean and null primitives: boolean and null.

Info! 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).


Float and Double:

Floating Point Numbers: Unlike whole numbers, floating point numbers have fractional parts that we express with a decimal point. e.g. 3.14159.
Floating point numbers are also known as real numbers. We use floating point number when we need more precision in calculations

Float is a single precision number, whereas double is a double precision number.

Precision refers to the format and amount of space occupied by the type. Single precision occupies 32 bits (so has a width of 32) and a Double precision occupies 64 bits (and thus has a width of 64).

Code Output

package lectures;

public class floatAndDouble {

	public static void main(String[] args) {
	
		float myMinFloatValue = Float.MIN_VALUE;
		float myMaxFloatValue = Float.MAX_VALUE;
		System.out.println("Float Min Value = "+myMinFloatValue);
		System.out.println("Float Max Value = "+myMaxFloatValue);
		
		double myMinDoubleValue = Double.MIN_VALUE;
		double myMaxDoubleValue = Double.MAX_VALUE;
		System.out.println("double Min Value = "+myMinDoubleValue);
		System.out.println("double Max Value = "+myMaxDoubleValue);
		
		int myIntValue = 5;
		float myFloatValue = 5f;
		double myDoubleValue = 5d;
		System.out.println("int = "+myIntValue);
		System.out.println("float = "+myFloatValue);
		System.out.println("double = "+myDoubleValue);
		
		//float myNewFloatValue = 5.25; //=> This will give error
		//because by default every deciaml value is considered double.
		//if we want to use it as float, we need to use 'f' as suffix.
		double myNewDoubleValue = 5.25d;
	}

}
		

Float Min Value = 1.4E-45
Float Max Value = 3.4028235E38
double Min Value = 4.9E-324
double Max Value = 1.7976931348623157E308
int = 5
float = 5.0
double = 5.0
		


Float is precise up to 7 decimal places.

Double is precise up to 16 decimal places.

Code Output

int divIntValue = 5/3;

//float div1FloatValue = (5 / 3)f; //This will give error, invalid
float divFloatValue = 5f / 3f;

//double divDoubleValue = 5d /3d;
//As double is being used by default, we can keep it simple as below
double divDoubleValue = 5.00 /3.00;
double div1DoubleValue = 5 /3;

System.out.println("int = "+divIntValue);
System.out.println("float = "+divFloatValue);
System.out.println("double = "+divDoubleValue);
System.out.println("double1 = "+div1DoubleValue);
		

int = 1
float = 1.6666666
double = 1.6666666666666667
double1 = 1.0
		

Info!
In general, float and double are great for general floating point operations. But both are not great to use where precise calculations are required - this is due to a limitation with how floating point numbers are stored, and not a Java problem as such.

But Java has a solution for this. Java has a class called BigDecimal that overcomes this.


Note! This is always to keep in mind that when precise calculations are necessary, floating point types should not be used. But for general calculation float and double are fine.



Char and Boolean:

Char:

"Char" and "Strings" are different. When we write anything within " " it is String, whereas Char can store 'single' character.

A char occupies 2 bytes of memory; or 16 bits and thus has a width of 16. The reason is not just a single byte is that it allows us to store UNICODE characters.

Unicode is an international encoding standard for use with different languages and scripts, by which each letter, digit, or symbol is assigned a unique numeric value that applies across different platforms and programs.

In English alphabet, we have letters A through Z. Meaning only 26 characters are needed in total to represent the entire English alphabet. But other languages need more characters, and often a lot more.

Unicode allows us to represent these languages and the way it works is by using a combination of two bytes that a char takes up in a memory it can represent and one of 65535 different type of characters. Sample Website for Unicode reference

Unicode ExampleOutput

public static void main(String[] args) {
		
	char myChar = 'D';
	char myUnicodeChar = '\u0044';
	System.out.println(myChar);
	System.out.println(myUnicodeChar);
}
		

D
D
		

Boolean Primitive Type:

A boolean value allows for two choices True or False, Yes or No, 1 or 0. In Java terms we have a boolean primitive type and it can be set to two values only i.e., true or false.



String Data Type:

The String is a datatype in Java, which is not a primitive type. It is actually a Class, but it enjoys a bit of favoritism in Java to make it easier to use than a regular class.

What is a String ?

A String is a sequence of characters. In the case of char , it could contain a single character only (regular character or Unicode character).

A String can contain a sequence of characters. A large number of characters. Technically it's limited by memory or the MAX_VALUE of an int which was 2.14 Billion. That's a lot of characters.

In addition to the eight primitive data types listed above, the Java programming language also provides special support for character strings via the java.lang.String class.

Enclosing the character string within double quotes will automatically create a new String object; for example, String s = "this is a string";. String objects are immutable, which means that once created, their values cannot be changed. The String class is not technically a primitive data type, but considering the special support given to it by the language, we'll probably tend to think of it as such.


	public static void main(String[] args) {
		
		String myString = "This is a String";
		System.out.println("myString is equal to "+myString);
		myString = myString + ", and this is more.";
		System.out.println("myString is equal to "+myString);
		myString = myString + " \u00A9 2020 ";
		System.out.println("myString is equal to "+myString);
		String numberString = "250.55";
		numberString = numberString + " 49.95 ";
		System.out.println(numberString);
		String lastString = " 10 ";
		int myInt = 50;
		lastString = lastString + myInt;
		System.out.println("Last String is equal to "+ lastString);
		//converted int to string
		
		double doubleNumber = 120.47d;
		lastString = lastString + doubleNumber;
		System.out.println("Last String is equal to "+ lastString);
		//converted double to string

	}

Output:


	myString is equal to This is a String
	myString is equal to This is a String, and this is more.
	myString is equal to This is a String, and this is more. © 2020 
	250.55 49.95 
	Last String is equal to  10 50
	Last String is equal to  10 50120.47

Strings in Java are Immutable

When we say we can delete characters out of a String, that's not strictly true. Because Strings in Java are immutable. This means we can't change a String after it's created. Instead, what happens is a new String is created.


 	int myInt = 50;
	lastString = lastString + myInt;
	System.out.println("Last String is equal to "+ lastString);
		
	double doubleNumber = 120.47d;
	lastString = lastString + doubleNumber;
	System.out.println("Last String is equal to "+ lastString);
 

So in case of this code, lastString doesn't get appended the value "120.47" instead a new String is created which consist of the previous of lastString plus a text representation of the double value 120.47.

As a result of a String being created, appending values like this is inefficient and not recommended.


Default Values:

It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type. Relying on such default values, however, is generally considered bad programming style.

Data Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
String (or any object)   null
boolean false

Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.


Overflow & Underflow

CodeOutput

	public class ByteShortIntLong {
						
		public static void main(String[] args) {
								
			System.out.println("Int");
			int myValue = 10000;
					
			int myMinIntValue = Integer.MIN_VALUE;
			int myMaxIntValue = Integer.MAX_VALUE;
								
			System.out.println("Integer Minimum Value = " + myMinIntValue);
			System.out.println("Integer Maximum Value = " + myMaxIntValue);
								
			System.out.println("Busted Max Value = " + (myMaxIntValue + 1));
			System.out.println("Busted Min Value = " + (myMinIntValue - 1));
								
			int maxIntValue = 2_147_483_647;
			//here we'll get error because we'll be changing it literally.
			System.out.println(myValue);
			System.out.println(maxIntValue);
								
			System.out.println("\nByte");
								
			byte myMinByteValue = Byte.MIN_VALUE;
			byte myMaxByteValue = Byte.MAX_VALUE;
			System.out.println("Byte Min Value = " + myMinByteValue);
			System.out.println("Byte Max Value = " + myMaxByteValue);
								
			System.out.println("\nShort");
								
			short myMinShortValue = Short.MIN_VALUE;
			short myMaxShortValue = Short.MAX_VALUE;
			System.out.println("Short Min Value = " + myMinShortValue);
			System.out.println("Short Max Value = " + myMaxShortValue);
			
			System.out.println("\nlong");
			
			long mylongValue = 100L; //Representation of a long value
			long myMinLongValue = Long.MIN_VALUE;
			long myMaxLongValue = Long.MAX_VALUE;
			System.out.println("Short Min Value = " + myMinLongValue);
			System.out.println("Short Max Value = " + myMaxLongValue);
			
			long bigLongLitralValue = 2_147_483_647L; 
			// If we don't type L, it will be taken as integer
			System.out.println("Big long litral value = "+ bigLongLitralValue);
		}
	}

	Int
	Integer Minimum Value = -2147483648
	Integer Maximum Value = 2147483647
	Busted Max Value = -2147483648
	Busted Min Value = 2147483647
	10000
	2147483647

	Byte
	Byte Min Value = -128
	Byte Max Value = 127

	Short
	Short Min Value = -32768
	Short Max Value = 32767

	long
	Short Min Value = -9223372036854775808
	Short Max Value = 9223372036854775807
	Big long litral value = 2147483647

In the above code:

OVERFLOW

System.out.println("Busted Max Value = " + (myMaxIntValue + 1));

Output: Busted Max Value = -2147483648

This is OVERFLOW. Because technically it's not possible to add +1 to the MAX_VALUE. So, somehow it will be adjusted by the compiler see a -ve sign in the output. Overflow: In case of max value.


UNDERFLOW

System.out.println("Busted Min Value = " + (myMinIntValue - 1));

Output: Busted Min Value = 2147483647

This is UNDERFLOW. This is giving positive value for MIN. Somehow adjusted by compiler. Underflow: In case of min value.

Now changing the values literally:

Now as we can see, maximum value of INT is "Integer Maximum Value = 2147483647". If we change it, e.g. 2147483648, it will give error. This is because we're trying to change the maximum value of int literally.

Info! Both int and byte have same Overflow and Underflow.


Literals

If we notice that the new keyword isn't used when initializing a variable of a primitive type. Primitive types are special data types built into the language; they are not objects created from a class.
A literal is the source code representation of a fixed value; literals are represented directly in our code without requiring computation. As shown below, it's possible to assign a literal to a variable of a primitive type:


	boolean result = true;
	char capitalC = 'C';
	byte b = 100;
	short s = 10000;
	int i = 100000;