Java fundamentals
Published: 2023-11-29 18:05:51



Java is an object-oriented programming language developed by Sun Microsystems and released in 1995. It has since become one of the most popular and widely used programming languages in the world. Now, let's talk about the aspects of Java:
Java is known for its "write once, run anywhere" (WORA) philosophy. This is made possible by the Java Virtual Machine (JVM), which allows Java applications to be executed on any device that has a JVM installed, regardless of the underlying hardware and operating system.
Java is a fully object-oriented programming language. This means that it follows the principles of encapsulation, inheritance, and polymorphism, providing a modular and flexible approach to software design and development.
Java syntax is similar to C-based languages such as C++ and C#, making it relatively easy for developers familiar with these languages to pick up Java quickly. It enforces strong typing and includes automatic memory management through garbage collection.
Java comes with a vast standard library that provides pre-built functionality for common tasks. This library, known as the Java API (Application Programming Interface), covers areas such as input/output, networking, data structures, and more.
Java has built-in support for multithreading, allowing developers to create concurrent applications that can perform multiple tasks simultaneously. This is crucial for developing responsive and efficient software.
Java has built-in security features, including a robust set of tools and APIs for cryptography, authentication, and access control. The Java Runtime Environment (JRE) includes a security manager that helps protect systems from malicious code.
Java has a large and active developer community. There are numerous frameworks, libraries, and tools available to Java developers, making it easier to build complex and feature-rich applications such as Spring, Hibernate, Apache Struts, and JavaFX. 
Java is used in a variety of application domains, including web development, mobile app development (Android applications are written in Java), enterprise applications, scientific applications, and more.
Now, let’s delve deeper into the core of Java and how it does work.
Java programs can run on any device that has a Java Virtual Machine (JVM) installed. Java programs are typically written in a text editor or integrated development environment (IDE) and have a ".java" extension. The Java source code is compiled into an intermediate form called bytecode by the Java Compiler (javac). Bytecode is a set of instructions for the Java Virtual Machine (JVM) rather than machine code for a specific hardware architecture. Bytecode is a low-level representation of the source code that is platform-independent, and It is stored in files with a ".class" extension. 
Now let’s talk more about what JVM, JRE, and JDK are.
Java Runtime Environment (JRE):
The JRE is a software package that includes the JVM, libraries, and other components required for running Java applications. It provides the runtime environment needed to execute Java programs.
Java Development Kit (JDK):
The JDK is a software development kit that includes the JRE along with tools for compiling, debugging, and monitoring Java applications. The JDK is not necessary to run applications and is used by programmers to create Java applications.
Class Loader:
The class loader is responsible for loading classes into the JVM as they are referenced by the Java program. The class loader loads classes from the local file system or from other sources like the internet.
Garbage Collection:
Java includes automatic memory management through garbage collection. The garbage collector runs in the background, identifying and reclaiming memory occupied by objects that are no longer in use.
Now, let’s learn about types in Java.
In Java, types can be broadly categorized into two main groups such as primitive and reference types (also known as non-primitive types or objects). Let's explore these two categories and the differences between them:
The first ones are primitive types. Primitive types are the basic data types provided by Java. They are simple and store single values. There are eight primitive data types in Java:
Numerical integer Types:
byte: 8-bit signed integer.
short: 16-bit signed integer.
int: 32-bit signed integer.
long: 64-bit signed integer.
Floating-Point Types:
float: 32-bit floating-point number.
double: 64-bit floating-point number.
For characters, we use char: 16-bit Unicode character.
For the Boolean datatype, we use boolean, which Represents true or false values.
Examples:
`int age = 25;
double salary = 50000.50;
char grade = 'A';
boolean isStudent = true;`

Reference Types (Non-Primitive Types):
Reference types include objects, arrays, and interfaces. They are more complex and store references to memory locations where the actual data is stored. Reference types are instances of classes or interfaces.

Examples:
`String name = "John";
Object obj = new Object();
int[] numbers = {1, 2, 3, 4};`

Differences Between Primitive and Reference Types:
Memory Representation:

Primitive types store the actual values.
Reference types store references (memory addresses) to the actual data.
Mutability:

Primitive types are immutable. Once a value is assigned, it cannot be changed.
Reference types can be mutable, meaning the state of the object can be modified.
Methods:

Primitive types do not have methods associated with them.
Reference types have methods and can have complex behavior.
Default Values:

Primitive types have default values (e.g., 0 for numbers, false for boolean).
Reference types have a default value of null if not explicitly initialized.
Passing to Methods:

Primitive types are passed by value.
Reference types are passed by reference (the reference is passed by value).

Now, let’s learn about OOP in Java.
Object-Oriented Programming (OOP) is a programming paradigm that is centered around the concept of "objects," which can contain data in the form of fields (attributes or properties) and code, in the form of procedures (methods or functions). Java is an object-oriented programming language, and it follows the principles of OOP. The four main pillars of Object-Oriented Programming are:
Inheritance:
Definition: Inheritance is a mechanism that allows a class (subclass or derived class) to inherit properties and behaviors from another class (superclass or base class).
Purpose: It promotes code reusability and establishes a relationship between classes, creating a hierarchy.
Example in Java:
`class Animal {
    void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog is barking");
    }
}`

Encapsulation:

Definition: Encapsulation is the bundling of data (attributes) and methods that operate on the data into a single unit known as a class. It restricts access to some of the object's components.
Purpose: It helps in data hiding, protecting the integrity of the data, and providing a clear interface for interacting with the object.
Example in Java:

`class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String newName) {
        name = newName;
    }
}`

Abstraction:
Definition: Abstraction is the process of simplifying complex systems by modeling classes based on the essential properties and behaviors. It involves creating abstract classes and interfaces.
Purpose: It hides the complex implementation details and provides a clear and simple interface for the user.
Example in Java:

`abstract class Shape {
    abstract void draw();
}

class Circle extends Shape {
    void draw() {
        System.out.println("Drawing a circle");
    }
}`

Polymorphism:
Definition: Polymorphism allows objects of different types to be treated as objects of a common type. It includes method overloading and method overriding.
Purpose: It enables flexibility in programming and simplifies code, making it more generic.
Example in Java:

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

    double add(double a, double b) {
        return a + b;
    }
}`

These four pillars together provide a strong foundation for building modular, maintainable, and extensible software systems. They encourage best practices in software design, such as code reuse, separation of concerns, and a clear organization of code.