Unit 1: Java Fundamentals, Data Types, Operators and Control Statements

By Notes Vandar

1.1 History and Philosophy of Java

History of Java

Java is one of the most influential and widely used programming languages in the world. It was originally developed by James Gosling at Sun Microsystems (now part of Oracle Corporation) and released in 1995. The development of Java began in the early 1990s when Sun Microsystems sought to create a language for embedded systems in consumer electronics.

Key Milestones in Java’s History:
  1. 1991: The Green Project
    • Java started as a part of the Green Project, initiated by James Gosling, Mike Sheridan, and Patrick Naughton. It was aimed at creating a language for programming consumer electronics, such as interactive television.
    • Initially, the language was called Oak, named after the oak tree outside Gosling’s office.
  2. 1995: Public Release of Java 1.0
    • Sun Microsystems rebranded Oak to Java, and the first public version of Java (Java 1.0) was released in 1995.
    • Java gained popularity because it allowed developers to write programs once and run them anywhere (WORA: “Write Once, Run Anywhere”), making it platform-independent. This was achieved by running Java applications on the Java Virtual Machine (JVM).
    • The slogan “write once, run anywhere” highlighted Java’s ability to be run on any platform with a JVM, distinguishing it from languages like C and C++.
  3. Late 1990s: Rise of Applets and Enterprise Use
    • In the late 1990s, Java was used to develop applets (small programs) that could run in web browsers. While this technology eventually became less popular, it initially showcased Java’s potential for web-based applications.
    • Java quickly expanded into enterprise-level applications with the introduction of Java 2 Enterprise Edition (J2EE), solidifying its role in large-scale, server-side development.
  4. 2006: OpenJDK and Oracle Acquisition
    • In 2006, Sun Microsystems released much of Java as open source under the OpenJDK (Java Development Kit), making it more accessible to developers.
    • In 2010, Oracle Corporation acquired Sun Microsystems, making Oracle the steward of Java. Oracle continues to manage the ongoing development and updates of Java.
  5. Modern Java: New Features and Versions
    • Over time, Java has evolved to incorporate new features and tools. Starting from Java 8 (released in 2014), significant enhancements like lambda expressions, streams, and the Java Time API were introduced, modernizing the language and making it more functional.
    • Subsequent versions, including Java 9, 10, 11 (Long-Term Support, LTS), and beyond, introduced features like the Java Module System, Local Variable Type Inference (var), and other performance improvements.
    • Java is now widely used in areas like mobile development (via Android), web applications, scientific computing, and large-scale enterprise applications.

Philosophy of Java

The design and philosophy of Java were shaped by several guiding principles, which made it a versatile, secure, and platform-independent language. The key goals of Java’s design philosophy include:

  1. Simplicity, Familiarity, and Ease of Use
    • Java was designed to be easy to use and familiar to programmers coming from languages like C and C++. It eliminates many of the complexities and pitfalls of C++ (e.g., manual memory management, pointers) while retaining object-oriented concepts.
    • It aimed to reduce the number of bugs and make it easier to write robust, error-free code.
  2. Platform Independence
    • One of Java’s most famous and defining features is its ability to run on any device or operating system that has a Java Virtual Machine (JVM).
    • By compiling Java code into bytecode (intermediate representation) instead of machine code, Java applications can run on any platform that supports the JVM. This achieves the “Write Once, Run Anywhere” (WORA) principle.
  3. Security
    • Security was a major concern in Java’s design, especially since it was intended to run on networked devices and the web.
    • Java includes built-in security features such as the sandboxing model for applets (isolating them from the host system), bytecode verification, and access control mechanisms. These features help prevent malicious code from causing damage.
  4. Object-Oriented
    • Java is a fully object-oriented programming language, meaning it uses objects to represent both data and methods.
    • The language promotes key object-oriented principles such as inheritance, encapsulation, polymorphism, and abstraction, making it modular, reusable, and easier to maintain.
  5. Robustness
    • Java was designed to be a robust language, minimizing system crashes and memory leaks. It features automatic garbage collection, which automatically deallocates memory that is no longer in use, reducing the chances of memory-related errors.
    • Java also features strong type checking at compile time and runtime, reducing bugs related to type mismatches.
  6. Multithreading
    • From the outset, Java was designed with multithreading capabilities, allowing multiple threads to run concurrently within a program. This is especially useful for building high-performance applications like servers and games.
    • Java provides built-in support for thread management and synchronization, making it easier to develop applications that can handle multiple tasks simultaneously.
  7. Distributed and Networked Programming
    • Java was created with the ability to handle networked and distributed applications. It provides libraries that simplify network communication, making it easier to build client-server applications.
    • Features like Remote Method Invocation (RMI) and JavaBeans allow developers to create distributed, enterprise-level applications.
  8. High Performance
    • Although Java is an interpreted language, modern implementations of the JVM use techniques such as Just-In-Time (JIT) compilation to optimize performance and bring it closer to that of compiled languages like C++.
    • Performance improvements in JVMs over the years have significantly reduced Java’s initial reputation for being slower than other compiled languages.
  9. Dynamic and Extensible
    • Java is designed to adapt to evolving environments. Its dynamic nature allows for the addition of new classes, methods, and libraries at runtime.
    • Through features like reflection and the ability to load new classes dynamically, Java remains flexible in various runtime environments.
  10. Community and Ecosystem
  • Java has a large and active developer community, which contributes to its rich ecosystem of libraries, frameworks, and tools. This ensures that Java stays relevant and continues to evolve with modern programming needs.

 

1.2 Object-Oriented Programming (OOP)

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of “objects”, which can contain data (attributes) and code (methods) to manipulate that data. OOP provides a structured approach to program development by organizing software design around these objects. Java is one of the most popular languages that embraces the OOP model, making it central to understanding how Java applications are designed and developed.

Core Concepts of OOP:

  1. Classes and Objects
  2. Encapsulation
  3. Inheritance
  4. Polymorphism
  5. Abstraction

1. Classes and Objects

  • Class: A class is a blueprint or template for creating objects. It defines the properties (fields/attributes) and behaviors (methods) that the objects created from the class will have.
    • Example: A Car class may define properties like color, model, and speed, and methods like accelerate() and brake().
  • Object: An object is an instance of a class. Once a class is defined, multiple objects can be created from it, each representing a specific entity.
    • Example: If Car is the class, then myCar or yourCar could be individual objects representing specific cars.

In Java:

class Car {
SFacultytring color;
int speed;

void accelerate() {
speed += 10;
}

void brake() {
speed -= 10;
}
}

public class Main {
public static void main(String[] args) {
Car myCar = new Car(); // Creating an object
myCar.color = "Red"; // Accessing properties
myCar.accelerate(); // Calling methods
System.out.println(myCar.speed);
}
}

2. Encapsulation

Encapsulation is the concept of restricting access to certain components of an object, so they cannot be accessed directly from outside the class. This is done by marking class variables as private and providing getter and setter methods for accessing and modifying them.

Encapsulation helps in:

  • Data hiding: Keeping the internal workings of an object hidden from the outside.
  • Control over data: Allows controlled access and modification of the object’s attributes.

In Java:

class Person {
private String name;

public void setName(String name) { // Setter method
this.name = name;
}

public String getName() { // Getter method
return name;
}
}

public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setName(“John”);
System.out.println(person.getName());
}
}


3. Inheritance

Inheritance is a mechanism where one class can inherit the properties and behaviors of another class. The class that is inherited from is called the superclass or parent class, and the class that inherits is called the subclass or child class.

Inheritance promotes code reuse and helps in creating hierarchical relationships between classes.

  • Single Inheritance: A subclass inherits from only one superclass.
  • Multilevel Inheritance: A class can inherit from a subclass, creating multiple levels.

In Java:

class Animal {
void eat() {
System.out.println(“This animal eats food.”);
}
}

class Dog extends Animal { // Inheriting from Animal
void bark() {
System.out.println(“The dog barks.”);
}
}

public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat(); // Inherited method
myDog.bark();
}
}


4. Polymorphism

Polymorphism allows objects to be treated as instances of their parent class, rather than their actual class. This makes it possible for the same method to behave differently based on the object calling it. There are two types of polymorphism:

  1. Compile-time Polymorphism (Method Overloading): Multiple methods with the same name but different parameters.
  2. Run-time Polymorphism (Method Overriding): A subclass can provide a specific implementation of a method that is already defined in its parent class.
  • Overloading:

    class MathOperations {
    int add(int a, int b) {
    return a + b;
    }

    double add(double a, double b) { // Overloaded method
    return a + b;
    }
    }

    public class Main {
    public static void main(String[] args) {
    MathOperations mo = new MathOperations();
    System.out.println(mo.add(2, 3)); // Calls int version
    System.out.println(mo.add(2.5, 3.5)); // Calls double version
    }
    }

  • Overriding:

    class Animal {
    void sound() {
    System.out.println(“Animal makes a sound”);
    }
    }

    class Dog extends Animal {
    void sound() { // Overriding the method
    System.out.println(“Dog barks”);
    }
    }

    public class Main {
    public static void main(String[] args) {
    Animal myDog = new Dog(); // Run-time polymorphism
    myDog.sound(); // Calls overridden method in Dog class
    }
    }


5. Abstraction

Abstraction refers to the concept of hiding the complex implementation details of a system and only exposing the necessary parts to the user. It focuses on the “what” rather than the “how.”

In Java, abstraction is achieved using:

  • Abstract classes: A class that cannot be instantiated and may contain abstract methods (methods without a body).
  • Interfaces: A completely abstract class that can only have abstract methods (until Java 8, which introduced default methods).
  • Abstract Class:

    abstract class Animal {
    abstract void sound(); // Abstract method, no body
    }

    class Dog extends Animal {
    void sound() {
    System.out.println(“Dog barks”);
    }
    }

    public class Main {
    public static void main(String[] args) {
    Animal myDog = new Dog();
    myDog.sound();
    }
    }

  • Interface:

    interface Animal {
    void sound(); // Interface method
    }

    class Dog implements Animal {
    public void sound() {
    System.out.println(“Dog barks”);
    }
    }

    public class Main {
    public static void main(String[] args) {
    Animal myDog = new Dog();
    myDog.sound();
    }
    }


Advantages of Object-Oriented Programming

  1. Modularity: Code is organized into objects, making it more manageable and modular.
  2. Reusability: Classes and objects can be reused in different programs or contexts, promoting code reuse.
  3. Maintainability: OOP promotes cleaner and more maintainable code by separating concerns.
  4. Security: Encapsulation allows sensitive data to be hidden from external access, enhancing security.
  5. Flexibility: Through inheritance and polymorphism, OOP enables flexibility and the ability to extend existing code without modification.

 

1.3 Java Development Kit (JDK)

The Java Development Kit (JDK) is a crucial tool for developing Java applications. It provides the necessary tools, libraries, and utilities to write, compile, and run Java programs. The JDK is the official development environment for building Java applications and is freely available from Oracle.

Key Components of the JDK

The JDK consists of several important components:

  1. Java Compiler (javac)
  2. Java Runtime Environment (JRE)
  3. Java Virtual Machine (JVM)
  4. Development Tools
  5. Java Libraries

1. Java Compiler (javac)

The Java compiler (javac) is responsible for converting the human-readable Java source code into bytecode, which is a platform-independent representation of the program. Bytecode is executed by the Java Virtual Machine (JVM).

  • The compiler takes .java files and compiles them into .class files containing bytecode.
  • Example:
    javac MyProgram.java

After running this command, the MyProgram.class file will be generated, which can be executed by the JVM.


2. Java Runtime Environment (JRE)

The Java Runtime Environment (JRE) is a subset of the JDK that provides the libraries and components necessary to run Java programs. While the JDK is used for developing Java programs, the JRE is needed only to run them.

The JRE consists of:

  • Java Class Libraries: Pre-built classes that developers can use in their programs, like java.util, java.io, and others.
  • Java Virtual Machine (JVM): The core component that executes the compiled bytecode.

In essence, the JRE provides the minimum requirements to run a Java application, but it does not include development tools like the compiler.


3. Java Virtual Machine (JVM)

The Java Virtual Machine (JVM) is the heart of Java’s “Write Once, Run Anywhere” philosophy. The JVM is responsible for executing the bytecode generated by the compiler.

  • The JVM abstracts the underlying platform (Windows, Mac, Linux, etc.) and allows Java programs to run on any system that has a JVM installed.
  • Each operating system has its own JVM implementation, but the bytecode remains the same, making Java platform-independent.

The JVM performs several tasks:

  • Class loading: Dynamically loads classes during runtime.
  • Bytecode verification: Ensures the bytecode adheres to Java’s security and access rules.
  • Execution: Executes the bytecode using either an interpreter or Just-In-Time (JIT) compiler for performance.

4. Development Tools

The JDK includes several development tools that are useful for writing, testing, and debugging Java applications:

  1. javac: The Java compiler for compiling .java files into .class bytecode files.
  2. java: The command used to run Java applications.
  3. javadoc: A tool to generate documentation from Java source code comments.
  4. jdb: A debugger that helps developers find and fix bugs in their Java programs.
  5. jar: A tool for creating and managing JAR (Java ARchive) files, which bundle together compiled Java classes and associated resources.
  6. javap: A disassembler that provides insight into the contents of compiled .class files.
  7. jps, jstack, jstat, jmap, jconsole: Various monitoring and profiling tools to analyze the performance of Java applications.

5. Java Libraries (API)

The JDK comes with a rich set of pre-built Java libraries, collectively known as the Java API (Application Programming Interface). These libraries provide the functionality needed for tasks like file handling, networking, data structures, graphical user interface (GUI) development, and much more.

Key packages include:

  • java.lang: Fundamental classes like String, Math, System, and others.
  • java.util: Utility classes for data structures (like ArrayList, HashMap), date and time, etc.
  • java.io: Input/output classes for reading and writing files and data streams.
  • java.net: Networking classes for developing networked applications.
  • java.awt and javax.swing: Classes for building graphical user interfaces (GUI).

Installing the JDK

To develop Java programs, the JDK must be installed on your machine. It is available for download from the Oracle website and can be installed on different operating systems, such as Windows, macOS, and Linux.

  • After installation, you need to set up the environment variables (JAVA_HOME and PATH) to ensure that Java commands can be run from the command line.

Example (Windows):

set JAVA_HOME=C:\Program Files\Java\jdk-11.0.2
set PATH=%PATH%;%JAVA_HOME%\bin

This ensures that commands like javac and java can be executed from any directory in the terminal.


Workflow of Java Development with the JDK

  1. Write the Code: Write Java source code using any text editor or an Integrated Development Environment (IDE) like Eclipse or IntelliJ IDEA.
  2. Compile the Code: Use the javac command to compile the source code into bytecode.
    javac MyProgram.java

    This generates a .class file with bytecode.

  3. Run the Program: Use the java command to run the compiled program.
    java MyProgram

    This will execute the main() method of the class, and the JVM will interpret or compile the bytecode into machine code.

  4. Debug and Optimize: Use debugging tools like jdb to step through the code and resolve any errors. Profiling tools like jconsole can be used to monitor performance.

JDK vs JRE vs JVM

  • JVM: Executes bytecode and abstracts the underlying operating system.
  • JRE: Contains the JVM and the class libraries required to run Java applications.
  • JDK: Includes the JRE and additional tools (compiler, debugger, etc.) for developing Java applications.

 

1.4 A First Simple Java Program

Let’s go through the process of writing, compiling, and running a simple Java program. Java programs typically follow a structure where they are organized into classes, and every Java program must contain a main method, which serves as the entry point for the application.

Here’s how you can write a basic Java program that prints a message to the console.


Steps to Create Your First Java Program

Step 1: Write the Code

The following is a simple Java program that prints “Hello, World!” to the console.

// MyFirstProgram.java

public class MyFirstProgram {
// The main method serves as the entry point of the program
public static void main(String[] args) {
// This line prints “Hello, World!” to the console
System.out.println(“Hello, World!”);
}
}

Explanation:

  1. public class MyFirstProgram:
    • This defines a class named MyFirstProgram. Every Java application contains at least one class.
    • The name of the class should match the filename, so this file should be saved as MyFirstProgram.java.
  2. public static void main(String[] args):
    • This is the main method. It’s the entry point of any Java program. When you run the program, the JVM looks for the main method to start the execution.
    • String[] args: This parameter is used to accept command-line arguments if needed.
  3. System.out.println("Hello, World!");:
    • This line prints the text “Hello, World!” to the console. System.out is Java’s standard output stream, and println is used to print text followed by a new line.

Step 2: Compile the Code

  1. Save the code in a file named MyFirstProgram.java.
  2. Open a terminal or command prompt and navigate to the directory where the file is saved.
  3. Use the following command to compile the Java file:
    javac MyFirstProgram.java

    This will generate a file called MyFirstProgram.class, which contains the compiled bytecode.


Step 3: Run the Program

Once the file is compiled, you can run it using the Java Virtual Machine (JVM) with the java command.

java MyFirstProgram

When you run the above command, you should see the following output:

Hello, World!

How It Works

  1. Compilation: The javac compiler takes the Java source code and translates it into bytecode (stored in .class files). The bytecode is platform-independent, meaning it can be executed on any operating system with a Java Virtual Machine (JVM).
  2. Execution: The java command starts the JVM, which interprets the bytecode and runs the program. The main method is called, and the statement inside it (System.out.println) prints “Hello, World!” to the console.

Structure of a Java Program

Here’s a breakdown of a basic Java program structure:

// Comments in Java are written like this. They are not executed by the program.

public class ClassName {
// The main method is the entry point of any Java program.
public static void main(String[] args) {
// Code statements go inside the main method.
// This will print text to the console.
System.out.println(“Your message here”);
}
}

Key Elements:

  • Class Declaration (public class ClassName): Every Java program is organized into classes. The class name must match the filename.
  • Main Method (public static void main(String[] args)): The method where execution starts. The main method must always be written exactly as public static void main(String[] args).
  • System.out.println: Used to print messages to the console.

Common Errors

  1. Missing Main Method: If the main method is missing, the JVM will throw an error:
    Error: Main method not found in class MyFirstProgram, please define the main method as:
    public static void main(String[] args)
  2. Filename and Class Name Mismatch: If the filename doesn’t match the class name, you’ll get an error during compilation. For example, if your class is named MyFirstProgram but the file is saved as Program.java, you’ll see:
    error: class MyFirstProgram is public, should be declared in a file named MyFirstProgram.java
  3. Semicolon Mistakes: Every statement in Java must end with a semicolon (;). If a semicolon is missing, you’ll get a compilation error:
    error: ‘;’ expected

Expanding the Program

Once you’re familiar with the basic structure, you can start experimenting by expanding the program. For example, let’s modify the program to print multiple lines or perform simple operations:

public class MyFirstProgram {
public static void main(String[] args) {
System.out.println(“Hello, World!”);
System.out.println(“Welcome to Java programming.”);// Adding a simple arithmetic operation
int a = 10;
int b = 20;
System.out.println(“Sum of a and b: ” + (a + b));
}
}

Expected output:

Hello, World!
Welcome to Java programming.
Sum of a and b: 30

1.5 Packages in Java

Packages in Java are a way of organizing classes and interfaces into namespaces, providing modularity, reusability, and structure to large programs. By grouping related classes, packages help avoid name conflicts and make the code more manageable and maintainable.


What is a Package?

A package in Java is a collection of related classes, interfaces, and sub-packages. Think of it as a directory or folder that logically groups related functionality. For example:

  • The java.util package contains utility classes like collections, date and time utilities, etc.
  • The java.io package handles input/output operations.

Packages help:

  1. Prevent name conflicts: Two classes can have the same name but belong to different packages.
  2. Provide access control: Packages help control the visibility of classes, methods, and fields using access modifiers (public, protected, private, default).
  3. Facilitate code reusability: You can import packages and reuse classes across different projects.

Types of Packages

There are two types of packages in Java:

  1. Built-in Packages: These are predefined packages provided by Java, such as java.lang, java.util, and java.io.
  2. User-defined Packages: These are packages created by developers to group and organize their own classes and interfaces.

Using Built-in Packages

Java provides a rich set of built-in packages that you can use directly in your programs by importing them.

Example of using the java.util package to work with the ArrayList class:

import java.util.ArrayList;

public class MyProgram {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add(“Apple”);
list.add(“Banana”);
System.out.println(list);
}
}

  • import java.util.ArrayList;: This line imports the ArrayList class from the java.util package.
  • Without the import statement, you would have to refer to the class using the full package name, like java.util.ArrayList.

Creating User-defined Packages

You can create your own packages in Java to organize your classes. Here’s how:

  1. Define a Package: Use the package keyword at the top of the Java file.
  2. Organize Classes: Classes belonging to the same functionality can be grouped into a package.

Example: Creating and using a user-defined package

  1. Creating a Package:

// Save this file as MyPackageClass.java in a folder named “mypackage”
package mypackage;

public class MyPackageClass {
public void displayMessage() {
System.out.println(“Hello from MyPackageClass!”);
}
}

  1. Using the Package:

// Save this file outside the “mypackage” folder
import mypackage.MyPackageClass;

public class TestPackage {
public static void main(String[] args) {
MyPackageClass obj = new MyPackageClass();
obj.displayMessage();
}
}

Explanation:

  • package mypackage;: This declares that MyPackageClass.java belongs to the mypackage package.
  • To use this class in another program, you need to import the package using import mypackage.MyPackageClass;.
  • The folder structure should reflect the package name. In this case, MyPackageClass.java should be saved in a folder named mypackage.

The import Statement

The import statement allows you to access classes and interfaces from a package. There are two types of import statements:

  1. Specific class import: Imports only one class from the package.
    import java.util.Scanner;
  2. Wildcard import: Imports all classes from the package.
    import java.util.*;

Note: Using wildcard imports (*) is generally discouraged in large projects as it may lead to unnecessary class loading and potential naming conflicts.


Default Package

If you don’t specify a package using the package keyword, the class belongs to the default package. The default package doesn’t need to be explicitly imported, but using it is considered poor practice in large projects because it limits reusability and organization.


Package Naming Conventions

  • Naming conventions: Package names are usually written in all lowercase to avoid conflicts with class names.
  • Domain-based naming: For larger applications, it’s common to use domain names in reverse as package names. For example:
    • A company with the domain example.com might create a package structure like this:
      com.example.projectname
    • This prevents naming conflicts with other organizations.

Access Control in Packages

Packages, combined with access control modifiers, help manage visibility and encapsulation in Java:

  • public: Classes, methods, and fields that are marked as public are accessible from any other class or package.
  • protected: Accessible within the same package or subclasses.
  • default (package-private): If no access modifier is specified, the member is accessible only within its own package.
  • private: Accessible only within the class where it is defined.

Sub-Packages

A package can contain other packages, creating a hierarchy. For example:

com
└── example
└── utilities

Here, utilities is a sub-package of example, which is a sub-package of com. To use a class from a sub-package, the full package name must be specified in the import statement:

import com.example.utilities.UtilityClass;

Java Package Examples

Some common built-in Java packages include:

  1. java.lang: Contains fundamental classes like String, Math, Integer, and Thread. This package is automatically imported in every Java program.
  2. java.util: Provides utility classes such as collections (e.g., ArrayList, HashMap), date/time utilities, and more.
  3. java.io: Contains classes for input and output, such as File, InputStream, OutputStream, etc.
  4. java.nio: Provides non-blocking I/O operations.
  5. java.sql: Contains classes for database connectivity and operations.
  6. javax.swing: Contains classes for building graphical user interfaces (GUIs).

 

1.6. Java’s Data Types

Java’s data types are divided into two main categories: Primitive and Non-Primitive types. Below, we explore each type and its uses, focusing on integers, characters, floating-point numbers, strings, arrays, and booleans.

1.6.1 Integers

Integer types are used to store whole numbers (both positive and negative) without decimal points. Java provides four different types of integers based on their size and range:

  1. byte:
    • Size: 8 bits
    • Range: -128 to 127
    • Example:
      byte smallNumber = 100;
  2. short:
    • Size: 16 bits
    • Range: -32,768 to 32,767
    • Example:
      short mediumNumber = 15000;
  3. int:
    • Size: 32 bits
    • Range: -2^31 to 2^31 – 1 (Approx. -2 billion to +2 billion)
    • Example:
      int largeNumber = 1000000;
  4. long:
    • Size: 64 bits
    • Range: -2^63 to 2^63 – 1 (Very large range)
    • Example:
      long veryLargeNumber = 10000000000L; // The ‘L’ indicates a long literal.

1.6.2 Characters

In Java, the char data type is used to store a single character (like a letter or symbol). It uses Unicode encoding, allowing it to represent characters from different languages.

  • Size: 16 bits (2 bytes)
  • Range: 0 to 65,535 (unsigned)
  • Example:
    char grade = ‘A’;
    char letter = ‘\u0041’; // Unicode representation of ‘A’

1.6.3 Floating Point Types

Floating-point types are used for representing numbers with decimal points (real numbers). Java has two types of floating-point data types:

  1. float:
    • Size: 32 bits (4 bytes)
    • Precision: 6-7 decimal digits
    • Range: ±3.40282347E+38F
    • Example:
      float pi = 3.14F; // ‘F’ or ‘f’ indicates a float literal.
  2. double:
    • Size: 64 bits (8 bytes)
    • Precision: 15 decimal digits
    • Range: ±1.79769313486231570E+308
    • Example:
      double gravity = 9.80665;

For most calculations that involve decimal numbers, double is the preferred type as it provides better precision.

 

1.6.4 Strings

Strings in Java are non-primitive data types that represent sequences of characters. They are objects of the String class and provide many useful methods for manipulating text.

  • Example:
    String greeting = “Hello, World!”;

Strings are immutable in Java, meaning that once a string is created, it cannot be changed. However, new strings can be created based on modifications to existing ones.

 

1.6.5 Arrays

An array is a collection of elements of the same data type, stored in contiguous memory locations. Arrays in Java are objects, and they can store both primitive data types and non-primitive types (like objects).

  • Declaring an array:
    int[] numbers = {1, 2, 3, 4, 5}; // An array of integers
    String[] names = {“Alice”, “Bob”, “Charlie”}; // An array of strings
  • Accessing array elements:
    int firstNumber = numbers[0]; // Accessing the first element
    names[1] = “John”; // Changing the second element

Arrays in Java are zero-indexed, meaning the first element is accessed at index 0, the second element at index 1, and so on.


1.6.6 The Boolean Type

The boolean type represents only two possible values: true or false. Booleans are typically used for conditions, decision-making, and control flow (such as in if statements and loops).

  • Example:
    boolean isJavaFun = true;
    boolean isRaining = false;

Unlike other primitive types, boolean does not have a defined size, but it’s optimized by the Java Virtual Machine (JVM).

 

1.7 Literals

In Java, literals represent fixed values that are directly used in the program. These values can be assigned to variables or used in expressions. Java supports different types of literals such as integer literals, floating-point literals, boolean literals, character literals, and string literals. This section will focus on special types of literals like hexadecimal, octal, and binary literals, as well as character escape sequences and string literals.


1.7.1 Hex, Octal, and Binary Literals

Java allows you to represent integer literals in hexadecimal, octal, and binary formats, in addition to the usual decimal format.

  1. Hexadecimal Literals:
    • Represented by prefixing the number with 0x or 0X.
    • Digits can be from 0-9 and letters from A-F (representing 10-15).
    • Example:
      int hexValue = 0x1A; // Equivalent to 26 in decimal
  2. Octal Literals:
    • Represented by prefixing the number with 0.
    • Digits can be from 0-7.
    • Example:
      int octalValue = 012; // Equivalent to 10 in decimal
  3. Binary Literals:
    • Introduced in Java 7, binary literals are represented by prefixing the number with 0b or 0B.
    • Digits can only be 0 or 1.
    • Example:
      int binaryValue = 0b1010; // Equivalent to 10 in decimal

1.7.2 Character Escape Sequences

Character literals in Java can represent special characters that cannot be typed directly in code by using escape sequences. Escape sequences are a combination of a backslash (\) followed by a character or a series of digits.

Common Escape Sequences:

  • \n: New line
    • Example:
      System.out.println(“Hello\nWorld”);
  • \t: Tab
    • Example:
      System.out.println(“Hello\tWorld”);
  • \\: Backslash
    • Example:
      System.out.println(“Backslash: \\”);
  • \': Single quote
    • Example:
      char singleQuote = ‘\”;
  • \": Double quote
    • Example:
      String quote = “He said, \”Java is awesome!\””;
  • \r: Carriage return
    • Example:
      System.out.println(“Carriage return\rExample”);
  • \b: Backspace
    • Example:
      System.out.println(“Hello\bWorld”);
  • \uXXXX: Unicode escape (where XXXX is a 4-digit hexadecimal number representing a Unicode character)
    • Example:
      char unicodeChar = ‘\u0041’; // Unicode for ‘A’

1.7.3 String Literals

A string literal is a sequence of characters enclosed in double quotes. In Java, strings are objects of the String class, which provides various methods to manipulate and process text.

  • Example of a simple string literal:
    String greeting = “Hello, World!”;
  • String concatenation: Strings can be concatenated (joined together) using the + operator.
    String fullName = “John” + ” ” + “Doe”; // Result: “John Doe”
  • Escape sequences in strings: Special characters can be included in string literals using escape sequences (e.g., \n for a new line or \" for double quotes).
    String message = “He said, \”Java is powerful!\””;

Multi-line String Literals:

Java doesn’t natively support multi-line string literals (until Java 13 with text blocks), but you can use the newline escape (\n) for line breaks.

  • Example:
    String poem = “Roses are red,\nViolets are blue,\nJava is great,\nAnd so are you!”;

With Java 13+, text blocks allow for multi-line strings:

  • Example:
    String json = “””
    {
    “name”: “John”,
    “age”: 30
    }
    “””;

1.8 Variables and Constants

In Java, variables and constants are used to store data in memory. Variables can change their values during program execution, while constants retain the same value once they are initialized. Understanding the proper use of variables and constants is crucial for writing clear and maintainable code.


1.8.1 Variables

A variable is a container for storing data values. Each variable in Java has a specific data type that defines what kind of values it can hold (such as integers, floating-point numbers, characters, or strings).

Declaring Variables

Variables must be declared before they can be used. A declaration specifies the data type and variable name.

  • Syntax:
    dataType variableName;
  • Example:
    int age; // Declares an integer variable
    double salary; // Declares a floating-point variable

Initializing Variables

Variables can be initialized at the time of declaration or later in the program.

  • Syntax:
    dataType variableName = value;
  • Example:
    int age = 25; // Declares and initializes ‘age’ with 25
    double salary = 55000.75; // Declares and initializes ‘salary’

Types of Variables

In Java, variables can be categorized into the following types:

  1. Local Variables:
    • Declared inside methods, constructors, or blocks.
    • Accessible only within the scope where they are defined.
    • Example:
      public void myMethod() {
      int localVar = 10; // Local variable
      }
  2. Instance Variables (Non-static fields):
    • Declared inside a class but outside any method.
    • Each instance (object) of the class has its own copy of the instance variables.
    • Example:
      class Car {
      String model; // Instance variable
      }
  3. Static Variables (Class variables):
    • Declared with the static keyword.
    • Shared among all instances of the class.
    • Example:
      class Car {
      static int numberOfCars; // Static variable
      }

1.8.2 Constants

A constant in Java is a variable whose value cannot be changed after it has been initialized. Constants are declared using the final keyword, and they must be initialized when they are declared.

  • Syntax:
    final dataType CONSTANT_NAME = value;

By convention, constant names are usually written in uppercase with words separated by underscores.

  • Example:
    final double PI = 3.14159; // Declares a constant ‘PI’ with a value of 3.14159
    final int MAX_AGE = 100; // Declares a constant ‘MAX_AGE’

Once a constant is initialized, any attempt to change its value will result in a compilation error.


Key Differences Between Variables and Constants

Feature Variables Constants
Changeability Can change value during program execution Value remains constant once initialized
Declaration Declared without final Declared with final
Naming Convention Use camelCase for naming Use UPPER_CASE with underscores
Examples int age = 25; final double PI = 3.14159;

Example of Variables and Constants in Use

public class Main {
public static void main(String[] args) {
// Variable declaration and initialization
int age = 30;
double salary = 50000.50;

// Constant declaration
final double PI = 3.14159;

// Modifying variables
age = 35;
salary = 60000.75;

// Uncommenting the next line would cause an error
// because PI is a constant
// PI = 3.14; // This would throw a compile-time error

// Printing variables and constants
System.out.println(“Age: ” + age);
System.out.println(“Salary: ” + salary);
System.out.println(“PI: ” + PI);
}
}

1.9 Operators

In Java, operators are special symbols that perform operations on variables and values. Java has a rich set of operators that can be classified into several categories based on their functionality. Below, we will explore the different types of operators available in Java.


1.9.1 Arithmetic Operators

Arithmetic operators are used to perform basic mathematical operations.

Operator Description Example
+ Addition a + b
- Subtraction a - b
* Multiplication a * b
/ Division a / b
% Modulus (Remainder) a % b

Example:

int a = 10;
int b = 3;
int sum = a + b; // sum = 13
int difference = a – b; // difference = 7
int product = a * b; // product = 30
int quotient = a / b; // quotient = 3
int remainder = a % b; // remainder = 1

1.9.2 Relational Operators

Relational operators are used to compare two values. They return a boolean result (true or false).

Operator Description Example
== Equal to a == b
!= Not equal to a != b
> Greater than a > b
< Less than a < b
>= Greater than or equal to a >= b
<= Less than or equal to a <= b

Example:

int x = 5;
int y = 10;
boolean isEqual = (x == y); // isEqual = false
boolean isGreater = (x > y); // isGreater = false
boolean isLessOrEqual = (x <= y); // isLessOrEqual = true

1.9.3 Logical Operators

Logical operators are used to combine multiple boolean expressions.

Operator Description Example
&& Logical AND a && b
` `
! Logical NOT !a

Example:

boolean a = true;
boolean b = false;
boolean andResult = (a && b); // andResult = false
boolean orResult = (a || b); // orResult = true
boolean notResult = !a; // notResult = false

1.9.4 Bitwise Operators

Bitwise operators perform operations on individual bits of integer types.

Operator Description Example
& Bitwise AND a & b
` ` Bitwise OR
^ Bitwise XOR a ^ b
~ Bitwise Complement ~a
<< Left Shift a << 2
>> Right Shift a >> 2
>>> Unsigned Right Shift a >>> 2

Example:

int a = 5; // 0101 in binary
int b = 3; // 0011 in binary
int andResult = a & b; // andResult = 1 (0001)
int orResult = a | b; // orResult = 7 (0111)
int xorResult = a ^ b; // xorResult = 6 (0110)

1.9.5 Assignment Operators

Assignment operators are used to assign values to variables. Java provides several shorthand assignment operators.

Operator Description Example
= Simple assignment a = 5;
+= Add and assign a += 3; (equiv. a = a + 3;)
-= Subtract and assign a -= 2; (equiv. a = a - 2;)
*= Multiply and assign a *= 4; (equiv. a = a * 4;)
/= Divide and assign a /= 2; (equiv. a = a / 2;)
%= Modulus and assign a %= 3; (equiv. a = a % 3;)

Example:

int a = 10;
a += 5; // a = 15
a *= 2; // a = 30

1.9.6 Unary Operators

Unary operators operate on a single operand. They can be used to perform operations such as incrementing, decrementing, negating, or complementing a value.

Operator Description Example
+ Unary plus +a
- Unary minus -a
++ Increment ++a or a++
-- Decrement --a or a--

Example:

int a = 5;
int b = ++a; // b = 6, a = 6 (pre-increment)
int c = a–; // c = 6, a = 5 (post-decrement)

1.9.7 Ternary Operator

The ternary operator is a shorthand for the if-else statement. It takes three operands and is used to evaluate a boolean expression.

Syntax:

condition ? valueIfTrue : valueIfFalse;

Example:

int a = 10;
int b = 20;
int max = (a > b) ? a : b; // max = 20

1.9.8 Instanceof Operator

The instanceof operator is used to test whether an object is an instance of a specific class or interface.

Syntax:

object instanceof ClassName

Example:

String str = "Hello";
boolean isString = str instanceof String; // isString = true

1.10 Type Casting

Type casting in Java is the process of converting a variable from one data type to another. It is essential in programming when you need to ensure that the data types of variables are compatible for operations. Java supports two types of type casting: implicit (automatic) casting and explicit (manual) casting.


1.10.1 Implicit Casting (Widening Conversion)

Implicit casting occurs when a smaller data type is converted to a larger data type automatically by the Java compiler. This is known as widening conversion, where there is no risk of losing data since a larger data type can accommodate the values of a smaller data type.

Examples of Implicit Casting:

  • Converting int to long
  • Converting float to double

Example:

int num = 100;
long longNum = num; // Implicit casting from int to long
double doubleNum = longNum; // Implicit casting from long to double

System.out.println(“Integer: ” + num); // Output: 100
System.out.println(“Long: ” + longNum); // Output: 100
System.out.println(“Double: ” + doubleNum); // Output: 100.0


1.10.2 Explicit Casting (Narrowing Conversion)

Explicit casting is required when converting a larger data type to a smaller data type. This is known as narrowing conversion and must be done manually because it can result in a loss of data.

Examples of Explicit Casting:

  • Converting double to float
  • Converting long to int

Example:

double doubleNum = 9.78;
int intNum = (int) doubleNum; // Explicit casting from double to int

System.out.println(“Double: ” + doubleNum); // Output: 9.78
System.out.println(“Integer: ” + intNum); // Output: 9 (loss of precision)

In the example above, the decimal part is lost during the conversion from double to int.


1.10.3 Type Casting in Java

Java supports type casting for various data types, including primitives and objects. Here’s how to perform casting with different data types.

Casting Primitive Types:

  • When casting between primitive types, you can use both implicit and explicit casting.
  • Implicit casting: Automatically performed.
  • Explicit casting: Requires a cast operator.

Example:

float floatNum = 10.5f;
int intNum = (int) floatNum; // Explicit casting from float to int

System.out.println(“Float: ” + floatNum); // Output: 10.5
System.out.println(“Integer: ” + intNum); // Output: 10 (loss of decimal part)

Casting Objects:

Casting can also be used when dealing with objects and class hierarchies. When you have a subclass reference pointing to a superclass object, you can cast it back to the subclass type.

Example:

class Animal {
void sound() {
System.out.println(“Animal makes a sound”);
}
}

class Dog extends Animal {
void sound() {
System.out.println(“Dog barks”);
}
}

public class Main {
public static void main(String[] args) {
Animal animal = new Dog(); // Upcasting (implicit)
animal.sound(); // Output: Dog barks

Dog dog = (Dog) animal; // Downcasting (explicit)
dog.sound(); // Output: Dog barks
}
}


1.10.4 Type Casting with Arrays

You can also cast arrays, but the elements in the array must be compatible types.

Example:

Object[] objects = new String[5]; // Implicitly upcasting String array to Object array
objects[0] = “Hello”;

String[] strings = (String[]) objects; // Explicitly downcasting Object array to String array
System.out.println(strings[0]); // Output: Hello


1.10.5 Type Casting Rules

  1. Widening Casting:
    • No explicit cast required.
    • Safe as it does not lead to data loss.
  2. Narrowing Casting:
    • Explicit cast required.
    • May lead to data loss or precision loss.
  3. Object Casting:
    • Can only cast objects of compatible types.
    • Upcasting is safe and implicit.
    • Downcasting should be done carefully; use instanceof to avoid ClassCastException.

1.11 Control Statements

Control statements in Java dictate the flow of execution in a program. They help determine which blocks of code should run under certain conditions or how many times a particular section of code should execute. Control statements can be broadly categorized into decision-making statements and loop statements.


1.11.1 if Statement

The if statement is a fundamental control structure that allows you to execute a block of code only if a specified condition is true.

Syntax:

if (condition) {
// code to be executed if condition is true
}

Example:

int number = 10;

if (number > 5) {
System.out.println(“Number is greater than 5”);
}
// Output: Number is greater than 5

You can also use else and else if for additional conditions:

Example with else and else if:

 int number = 10;

if (number > 10) {
System.out.println(“Number is greater than 10”);
} else if (number == 10) {
System.out.println(“Number is equal to 10”);
} else {
System.out.println(“Number is less than 10”);
}
// Output: Number is equal to 10

1.11.2 switch Statement

The switch statement is used as an alternative to multiple if statements when comparing a variable against a list of values (known as cases).

Syntax:

switch (expression) {
case value1:
// code to be executed if expression equals value1
break;
case value2:
// code to be executed if expression equals value2
break;
default:
// code to be executed if expression does not match any case
}

Example:

int day = 3;
String dayName;

switch (day) {
case 1:
dayName = “Monday”;
break;
case 2:
dayName = “Tuesday”;
break;
case 3:
dayName = “Wednesday”;
break;
default:
dayName = “Invalid day”;
break;
}

System.out.println(“Day: ” + dayName); // Output: Day: Wednesday


1.11.3 Loop Statement

Loop statements allow you to execute a block of code multiple times. Java provides several types of loops:

  1. for Loop: Used when the number of iterations is known.
  2. while Loop: Used when the number of iterations is not known beforehand.
  3. do-while Loop: Similar to while, but guarantees at least one execution of the loop.

1.11.3.1 for Loop:

for (int i = 0; i < 5; i++) {
System.out.println(“Iteration: ” + i);
}
// Output: Iteration: 0
// Iteration: 1
// Iteration: 2
// Iteration: 3
// Iteration: 4

1.11.3.2 while Loop:

int i = 0;
while (i < 5) {
System.out.println(“Iteration: ” + i);
i++;
}
// Output: Iteration: 0
// Iteration: 1
// Iteration: 2
// Iteration: 3
// Iteration: 4

1.11.3.3 do-while Loop:

int j = 0;
do {
System.out.println(“Iteration: ” + j);
j++;
} while (j < 5);
// Output: Iteration: 0
// Iteration: 1
// Iteration: 2
// Iteration: 3
// Iteration: 4

1.11.4 continue Statement

The continue statement is used inside loops to skip the current iteration and continue with the next iteration of the loop.

Example:

for (int i = 0; i < 5; i++) {
if (i == 2) {
continue; // Skip the iteration when i is 2
}
System.out.println(“Iteration: ” + i);
}
// Output: Iteration: 0
// Iteration: 1
// Iteration: 3
// Iteration: 4

1.11.5 break Statement

The break statement is used to exit a loop or switch statement prematurely. It terminates the current loop or switch execution and transfers control to the statement following the loop or switch.

Example:

for (int i = 0; i < 5; i++) {
if (i == 3) {
break; // Exit the loop when i is 3
}
System.out.println(“Iteration: ” + i);
}
// Output: Iteration: 0
// Iteration: 1
// Iteration: 2
Important Questions
Comments
Discussion
0 Comments
  Loading . . .