JAVA 101 - A Complete Guide

JAVA 101 - A Complete Guide

If you want to know all concepts of java or just to refresh java concepts before an interview this blog would come in handy.

Hey there y'all,

Come and join my java learning journey. I went through 100's pages of "Java The Complete Reference" book and recorded the concept in this blog. I have curated them in question-and-answer format. Hence you can also give a read before going to an interview.

Bonus: As a prerequisite, I have also covered basics that would give you some insights.

Basics

  1. Programming Language?

    Covert our Ideas into code.

    Programming Language - Human readable language

    machine-readable language - 0's & 1's

  2. Types of Programming Language?

    • Procedural

    • Functional

    • Object-Oriented

  3. Procedural Programming

    • follows the concept of a "process-oriented" model.

    • specifies a series of well-structured steps/processes/procedures to compose a program

    • systematic order of statements eg:

      Java, C, C+, Python

  4. Functional Programming

    • writing program in pure "function"

    • functions - are bundles of code that can be reused

    • eg: python (partially)

  5. Object-Oriented Programming?

    • revolves around the concept of "object"

    • code(method) + data(fields) = object

  6. Static language?

    • Type checking in compile time

    • eg: int a = 10; (data type is mentioned)

    • compiler

  7. Dynamic language?

    • Type checking in run time

    • eg: a = 10; (data type not mentioned)

      type error can occur(as data type is not mentioned)

    • interpreter

  8. Flowchart

    • visualization of ideas

    • basic step carried out before we start code - making coding easy

  9. Pseudocode

    • Algorithm of a program, but without using any actual syntax.

    • carried out before coding

  10. high-level language vs low-level language

    | high-level language | low-level language | | --- | --- | | Programmer-friendly language | Machine-friendly language | | A compiler/interpreter is required to translate | An allocator is required to translate | | Can run on any platform | Machine dependant | | Easy to Understand | Difficult to understand | | C, C++, Java, Python | |

  11. compiler vs interpreter

    | Compiler | Interpreter | | --- | --- | | Coverts the entire program into byte code, then directly executed by the machine | directly executes the instruction into the machine-understandable language | | Code runs faster | Code runs slower | | displays all errors after compilation | displays errors of each line one by one | | eg: C, C++ | eg: Python |

  12. stack memory vs heap memory

    | Stack memory | Heap memory | | --- | --- | | Memory Allocation is first-in-last-out | Memory Allocation is Random | | Deallocation is Compiler | Deallocation is Programmer | | Linear data structure | Hierarchical data structure |

An Overview of Java

  1. Java

    It is simple, object-oriented, robust, multi-threaded, Architecture-Neutral, Interpreted & high-performance, and Dynamic language.

    Simple:

    • It is simple for professional programmers

    • as java inherits the syntax of C, C++

**Object-Oriented:**

* Java follows the "everything is an **object**" paradigm and "stay out of my way" **model** This object model of Java is simple and easy to extend.


**robust:**

* Java is a strictly typed language. It checks your code at compile-time as well as at run-time. Also provides **garbage collection** for unused objects.


**multi-threaded:**

* Java is designed to be multi-threaded. It allows to you write programs and do many things simultaneously.


**Architecture-Neutral:**

* At the time of Java creation, one of the main problems faced by programmers was that, there was no guarantee existed if you wrote a program today, it would run tomorrow - even on the same OS.

* OS upgrades, processor upgrades, and changes in core system resources. This makes the program malfunction.

* Java designers made alternates - their goal was **"write once; run anywhere, any time, forever"**


**Interpreted & high-performance:**

* Java byte code can be executed in any OS.

* Java bytecode can be easily interpreted into machine language for high performance by using a just-in-time compiler.


**Distributed:**

* Java can handle TCP/IP protocol.

* Also, support Remote Method Invocator(RIM), enables a program to invoke methods across the network.


**Dynamic language:**

* A source code written in one platform, that can be executed in any platform.

* And it also loads the class files at run time.

* Anything that happens at run time is considered Dynamic.
  1. How Java Code is executed

    • Java code(.java) is compiled into byte code(.class) using JVM.

    • Byte code(.class) is interpreted(just-in-time) to Machine Readable Code. using JDK and JRE

  2. Byte Code

    • Byte code - represented as a .class file

    • These are intermediate codes in java.

    • Cannot run directly, hence we need JVM

  3. Java Development Kit(JDK)

    • It is a package used to develop and run a program

    • It consists of :

      • JRE

      • development tools

      • Compiler - Javac

      • javacdocs

      • Interpreter/Loader

  4. Java Runtime Environment(JRE):

    • It is an installation package, that is used to only run the program.

    • It consists of:

      • JVM

      • Libraries

  5. Java Virtual Machine(JVM):

    • It is an interpreter/ loader which reads a .class file into binary data

    • Interpreter:

      • line by line execution

      • if one method is called many times, it will interpret again and again.

  6. (Just-In-Time)JIT:

    • if one method is called many times, JIT will reuse the machine code instead of interpreting again and again.

    • Makes execution fast.

  7. Java Architecture

  8. Working of a Java Architecture

  9. Two Paradigms

    • All program consists of code and data.

    • They are organized around code and data.

    • Using these two paradigms, the program is constructed.

      • the process-oriented model characterizes a program as a series of linear steps(Code)

      • Object-oriented programming organizes a program around its data.

  10. Abstraction

    • It uses hierarchical classification.

    • eg: When we look at a car, we only look at the object but not its subsystem.

    • the data from a process-oriented program can be transformed by abstraction into its component objects.

  11. OOP Principles

    Encapsulation

    • Binds together code and data

    • it's like a protective wrapper, that prevents the code defined outside the wrapper to access the code and data.

    • eg: Shifting gears do not turn on the headlights!

**Inheritance**

* It is a process in which one object acquires the property of another.

* eg: doc belongs to class mammals, which belongs to class animals.

* Without hierarchies, the object would need to define all of its characteristics.

* However, using an inheritance object has to mention only its unique features.

* It can inherit general attributes from its parents.


**Polymorphism**

* from greek, meaning "Many Forms"

* eg: one stack is used for integer, one for floating-point and one for a character in non-OOP

* but In java, a general set of stacks can be specified that share all same names.
  1. First Java Program

    prerequisite: Any code editor, download JDK
    • Open the code editor and create a file in the following format:

      Filename.java (Replace Filename with your desired filename)

    • Inside the file write your first program:

```java
public class Filename {
    public static void main(String args[]) {
        System.out.println("Hello World");
    }
}
```

> **public**
> 
> * To make our class available for everyone
>     
> 
> **class**
> 
> * It is a template for objects.
>     
> * The first letter should be in caps.
>     
> * The class name should be the same as the filename.
>     
> 
> **static**
> 
> * The main class could run without creating an object.
>     
> 
> **void**
> 
> * The return type of function \[i.e. No return type\]
>     
> 
> **main**
> 
> * The entry point of Java Program.
>     
> 
> **String args\[\]**
> 
> * Command line argument.
>     
> * String \[\] - is an array/collection of arrays.
>     
> 
> **System.out.println**
> 
> * Print Statement.
>     
  1. Input In Java:

    import java.util.Scanner;
    public class Filename {
        public static void main(String args[]) {
            Scanner userInput = new Scanner(System.in);
            System.out.println("Message: " + userInput);
        }
    }
    

    import

    • packages are the container for classes and whenever we want to use the features of another class that are defined in another package, we use the import keyword.

    • Used at beginning of our file to specify

      • classes

      • Java Packages

      • even static members

    java.util.Scanner

    • java.util is a package that contains a framework, classes, event models, date and time facilities, internationalization, and miscellaneous utility classes.

    • "." is used to denote the hierarchy. So the above statement will denote -
      java\util\Scanner

    • util: stands for utility and contains utility classes.

    • The scanner is a predefined class for taking inputs from the user.

    new

    • It is a keyword used to create an instance of a class or array object.

    Scanner()

    • It is an object which is used to mention where you are taking that input from (i.e. System.in)

    System.in

    • It is an InputStream which is typically connected to the keyboard input

      (i.e. It takes input from the keyboard)

    userInput

    • It means to create a new Object user-input of class Scanner.
  2. Lexical Issues

    • Whitespace: Java allows us to use the space key, tab key or simply to write in a new line is considered a whitespace.

    • Identifiers: Identifiers are names assigned to different constructs of a Java program, such as classes, methods, interfaces, variables, etc. There are certain rules for defining a valid java identifier. These rules must be followed, otherwise, we get a compile-time error.

      • The only allowed characters for identifiers are all alphanumeric characters([A-Z],[a-z],[0-9]), ‘$‘(dollar sign) and ‘_‘ (underscore). For example “name@” is not a valid java identifier as it contains a ‘@’ a special character.

      • Identifiers should not start with digits([0-9]). For example “123name” is not a valid java identifier.

      • Java identifiers are case-sensitive.

      • There is no limit on the length of the identifier but it is advisable to use an optimum length of 4 – 15 letters only.

      • Reserved Words can’t be used as an identifier. For example “int while = 20;” is an invalid statement as while is a reserved word. There are 53 reserved words in Java.

    • Literals: literals are the values allotted to identifiers / Any constant value which can be assigned to the variable is called literal or constant.

      It contains boolean, numeric, character, or string data.

      • Integral literals: For Integral data types (byte, short, int, long)

        int x = 100;

      • Floating-Point literal: (double, float)

        float x = 10.5;

        double y = 123.456;

      • Char literals

        char x = "a";

      • String literals

        String x = "Hello";

      • Boolean literals

        boolean x = true;

    • Comments: Comments can be used to explain Java code, and to make it more readable. It can also be used to prevent execution when testing alternative code.

      • Single-line Comments

        Single-line comments start with two forward slashes (//).

        Any text between // and the end of the line is ignored by Java (will not be executed).

        // this is a comment, which would not be executed.

      • Multi-line Comments

        Multi-line comments start with /* and ends with */.

        Any text between /* and */ will be ignored by Java.

        /* nothing

        would

        be printed */

    • Separator: there are a few characters that are used as separators.

      | Symbol | Name | Purpose | | --- | --- | --- | | () | Parentheses | Used to contain lists of parameters in method definition and invocation. Also used for defining precedence in expressions, containing expressions in control statements, and surrounding cast types. | | {} | Braces | Used to contain the values of automatically initialized arrays. Also used to define a block of code, for classes, methods, and local scopes. | | [] | Brackets | Used to declare array types. Also used when dereferencing array values. | | ; | Semicolon | Terminates statements. | | , | Comma | Separates consecutive identifiers in a variable declaration. Also used to chain statements together inside a for statement. | | . | Period | Used to separate package names from sub-packages and classes. Also used to separate a variable or method from a reference variable. |

  3. Reserved Words

    Any programming language reserves some words to represent functionalities defined by that language. These words are called reserved words. They can be briefly categorized into two parts: keywords(50) and literals(3). Keywords define functionalities and literals define value.

  4. Keywords

    Keywords are particular words that act as a key to a code. These are predefined words by Java so they cannot be used as a variable or object name or class name.

    List of Java Keywords

  5. Data Type

    • Primitive Data Types

      A primitive data type specifies the size and type of variable values, and it has no additional methods.

      There are eight primitive data types in Java:

| 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 9,223,372,036,854,775,807 |
| `float` | 4 bytes | Stores fractional numbers. Sufficient for storing 6 to 7 decimal digits |
| `double` | 8 bytes | Stores fractional numbers. Sufficient for storing 15 decimal digits |
| `boolean` | 1 bit | Stores true or false values |
| `char` | 2 bytes | Stores a single character/letter or ASCII values |

* Non-primitive data types are called **reference types** because they refer to objects.

    The main difference between **primitive** and **non-primitive** data types are:

    * Primitive types are predefined (already defined) in Java. Non-primitive types are created by the programmer and are not defined by Java (except for `String`).

    * Non-primitive types can be used to call methods to perform certain operations, while primitive types cannot.

    * A primitive type has always a value, while non-primitive types can be `null`.

    * A primitive type starts with a lowercase letter, while a non-primitive type starts with an uppercase letter.

    * The size of a primitive type depends on the data type, while non-primitive types have all the same size.


    Examples of non-primitive types are **Strings, Arrays, Classes, Interfaces**, etc.
  1. Array

    An array is a group of liked typed variables that are referred to by a common name.

    • One dimensional array

      • They are lists of liked typed variables.

      • To create an array, you must first create an array variable of the desired type type var-name[]; (here type is element type which determines datatype i.e. var-name)

          class NewArray {
              public static void main(String[] args)
              {
                  // declares an Array of integers.
                  int[] arr;
                  // allocating memory for 5 integers.
                  arr = new int[5];
                  // initialize the first elements of the array
                  arr[0] = 10;
                  // initialize the second elements of the array
                  arr[1] = 20;
                  // so on...
                  arr[2] = 30;
                  arr[3] = 40;
                  arr[4] = 50;
                  // accessing the elements of the specified array
                  for (int i = 0; i < arr.length; i++)
                      System.out.println("Element at index " + i
                                         + " : " + arr[i]);
              }
          }
        

        or this can be simply written as follow:

          class NewArray {
              public static void main(String[] args)
              {
                  // declare and initilize an Array of integers directly
                  int[] arr = {10, 20, 30, 40, 50};
                  // accessing the elements of the specified array
                  for (int i = 0; i < arr.length; i++)
                      System.out.println("Element at index " + i
                                         + " : " + arr[i]);
              }
          }
        
  2. Operators

    Operators are used to performing operations on variables and values.

    • Arithmetic Operators

      Arithmetic operators are used to performing common mathematical operations.

| Operator | Name | Description | Example |
| --- | --- | --- | --- |
| + | Addition | Adds together two values | x + y |
| \- | Subtraction | Subtracts one value from another | x - y |
| \* | Multiplication | Multiplies two values | x \* y |
| / | Division | Divides one value by another | x / y |
| % | Modulus | Returns the division remainder | x % y |
| ++ | Increment | Increases the value of a variable by 1 | ++x |
| \-- | Decrement | Decreases the value of a variable by 1 | \--x |

* Assignment operators

    Assignment operators are used to assigning values to variables.

    | Operator | Example | Same As |
    | --- | --- | --- |
    | \= | x = 5 | x = 5 |
    | += | x += 3 | x = x + 3 |
    | \-= | x -= 3 | x = x - 3 |
    | \*= | x \*= 3 | x = x \* 3 |
    | /= | x /= 3 | x = x / 3 |
    | %= | x %= 3 | x = x % 3 |
    | &= | x &= 3 | x = x & 3 |
    |  | \= | x |
    | ^= | x ^= 3 | x = x ^ 3 |
    | &gt;&gt;= | x &gt;&gt;= 3 | x = x &gt;&gt; 3 |
    | &lt;&lt;= | x &lt;&lt;= 3 | x = x &lt;&lt; 3 |

* Comparison operators

    Comparison operators are used to comparing two values (or variables).

    The return value of a comparison is boolean (`true` or `false`)

    | Operator | Name | Example |
    | --- | --- | --- |
    | \== | Equal to | x == y |
    | != | Not equal | x != y |
    | &gt; | Greater than | x &gt; y |
    | &lt; | Less than | x &lt; y |
    | &gt;= | Greater than or equal to | x &gt;= y |
    | &lt;= | Less than or equal to | x &lt;= y |

* Logical operators

    You can also test for `true` or `false` values with logical operators.

    Logical operators are used to determine the logic between variables or values

    | Operator | Name | Description | Example |
    | --- | --- | --- | --- |
    | && | Logical and | Returns true if both statements are true | x &lt; 5 &&  x &lt; 10 |
    |  |  |  | Logical or |
    | ! | Logical not | Reverse the result, and returns false if the result is true | !(x &lt; 5 && x &lt; 10) |

* Bitwise operators

    Bitwise operators are used to perform the manipulation of individual bits of a number.

    The bitwise logical operators are AND(&), OR(|), XOR(^), and NOT(~).
  1. Control Statement

    The statements in the code are executed according to the order in which they appear. However, Java provides statements that can be used to control the flow of Java code. Such statements are called control flow statements.

    Java provides three types of control flow statements.

    1. Decision-Making / Selection statements

      decision-making statements decide which statement to execute and when.

      • if statements - the "if" statement is used to evaluate a condition.

        1. Simple if statement - It evaluates a Boolean expression and enables the program to enter a block of code if the expression evaluates to true.

          if(condition) {

          statement 1; //executes when the condition is true

          }

        2. if-else statement - The if-else statement is an extension to the if-statement, which uses another block of code, i.e., the else block. The else block is executed if the condition of the if-block is evaluated as false.

          if(condition) {

          statement 1; //executes when the condition is true

          } else{

          statement 2; //executes when the condition is false

          }

        3. if-else-if ladder- The if-else-if statement contains the if-statement followed by multiple else-if statements.

          if(condition 1) {

          statement 1; //executes when condition 1 is true

          } else if(condition 2) {

          statement 2; //executes when condition 2 is true

          } else {

          statement 2; //executes when all the conditions are false

          }

        4. Nested if-statement- the if statement can contain an if or if-else statement inside another if or else-if statement.

          if(condition 1) {

          statement 1; //executes when condition 1 is true

          if(condition 2) {

          statement 2; //executes when condition 2 is true

          }

          else{

          statement 2; //executes when condition 2 is false

          }

          }

      • switch statement - Switch statements are similar to if-else-if statements. The switch statement contains multiple blocks of code called cases and a single case is executed based on the variable which is being switched. The switch statement is easier to use instead of if-else-if statements.

        switch (expression){

        case value1:

        statement1;

        break;

        ...

        case valueN:

        statementN;

        break;

        default:

        default statement;

        }

    2. Iteration / Loop statements - sometimes we need to execute the block of code repeatedly while some condition evaluates to true.

      • do while loop - The do-while loop checks the condition at the end of the loop after executing the loop statements. When the number of iterations is not known and we have to execute the loop at least once, we can use a do-while loop.

        It is also known as the exit-controlled loop since the condition is not checked in advance. The syntax of the do-while loop is given below.

        do {

        //statements

        } while (condition);

      • while loop - The while loop is also used to iterate over the number of statements multiple times. However, if we don't know the number of iterations in advance, it is recommended to use a while loop. Unlike for loop, the initialization and increment/decrement doesn't take place inside the loop statement in the while loop.

        It is also known as the entry-controlled loop since the condition is checked at the start of the loop. If the condition is true, then the loop body will be executed; otherwise, the statements after the loop will be executed.

        while(condition){

        //looping statements

        }

      • for loop - It enables us to initialize the loop variable, check the condition, and increment/decrement in a single line of code. We use the for loop only when we exactly know the number of times, we want to execute the block of code.

        for(initialization, condition, increment/decrement) {

        //block of statements

        }

      • for-each loop - Java provides an enhanced for loop to traverse the data structures like arrays or collections. In the for-each loop, we don't need to update the loop variable.

        for(data_type var : array_name/collection_name){

        //statements

        }

    3. Jump statements - Jump statements are used to transfer the control of the program to specific statements. In other words, jump statements transfer the execution control to the other part of the program.

      • break statement - the break statement is used to break the current flow of the program and transfer the control to the next statement outside a loop or switch statement. However, it breaks only the inner loop in the case of the nested loop.

        The break statement cannot be used independently in the Java program, i.e., it can only be written inside the loop or switch statement.

        for(data_type var : array_name/collection_name) {

        if(condition) {

        break;

        }

        }

      • **continue statement -**the continue statement doesn't break the loop, whereas, it skips the specific part of the loop and jumps to the next iteration of the loop immediately.

        for(data_type var : array_name/collection_name) {

        for (data_type var : array_name/collection_name) {

        if(condition) {

        continue;

        }

        }

        }

  2. Class in Java

    Class is a set of the object which shares common characteristics/ behavior and common properties/ attributes.
    Class is not a real-world entity. It is just a template or blueprint or prototype from which objects are created.
    Class does not occupy memory.
    Class is a group of variables of different data types and group of methods.

    Syntax:

    class classname {

    type instance_variable;

    type method(parameters) {

    //body

    }

    }

    data/variable inside the class is called an instance variable.

    method & variable inside the class are called members**.**

    class Box {
        double width, height, depth;
    }
    
  3. Object in Java

    The object is an instance of the class.

    An entity that has a state and behavior is known as an object e.g., a chair, bike, marker, pen, table, car, etc.

    Box myBox = new Box(); //create a box object called myBox
    
  4. Program using class and object:

    class Box {
        double width, height, depth;
    }
    class BoxProgram {
        public static void main(String args[]) {
            Box myBox = new Box();
            double volume;
            // assign value to myBox instance variable 
            myBox.width = 10;
            myBox.height = 20;
            myBox.depth = 15;
            volume = myBox.width * myBox.height * myBox.depth;
            System.out.println("Volume: " + volume);
        }
    }
    

    output:

    Volume: 3000.0

  5. Method in Java

    • It is a code that is executed when called.

    • code is contained within the class.

    • the method can be void / return value / take parameters.

      type-name (parameter-list) {

      //body

      }

    • Adding a method to a previously discussed example

      (a) void method

        class Box {
            double width, height, depth;
            //display volume of box
            void volume() {
                System.out.println("Volume: ");
                System.out.println(width * height * depth);
            }
        }
        class BoxProgram {
            public static void main(String args[]) {
                Box myBox1 = new Box();
                Box myBox2 = new Box();
                // assign value to myBox1's instance variable 
                myBox1.width = 10;
                myBox1.height = 20;
                myBox1.depth = 15;
                // assign value to myBox2's instance variable 
                myBox2.width = 3;
                myBox2.height = 6;
                myBox2.depth = 9;
                myBox1.volume(); //display volume of first box
                myBox2.volume(); //display volume of second box
            }
        }
      
> output:
> 
> Volume: 3000.0
> 
> Volume: 162.0

(b) `the method that has a return type` - what if you want to know the volume of the box but not display it? That could be done by returning the result.

```java
class Box {
    double width, height, depth;
    //display volume of box
    double volume() {
        return width * height * depth;
    }
}
class BoxProgram {
    public static void main(String args[]) {
        Box myBox1 = new Box();
        Box myBox2 = new Box();
        double volume;
        // assign value to myBox1's instance variable 
        myBox1.width = 10;
        myBox1.height = 20;
        myBox1.depth = 15;
        // assign value to myBox2's instance variable 
        myBox2.width = 3;
        myBox2.height = 6;
        myBox2.depth = 9;
        //display volume of first box
        myBox1.volume(); 
        System.out.println("Volume: " + volume);
         //display volume of second box
        myBox2.volume();
        System.out.println("Volume: " + volume);
    }
}
```

(c) the `method that takes a parameter`

> //here's an example
> 
> int square(int i) {
> 
> return i \* i;
> 
> }
> 
> // now square() will return whatever value is called.
> 
> //eg:
> 
> int x,y;
> 
> x = square(5); //25
> 
> y = square(3); //9

```java
class Box {
    double width, height, depth; //instance var
    double volume() { //method
        return width * height * depth;
    }
    void dimensions(double w, double h, double d) {
        width = w;
        height = h;
        depth = d;        
    }
}
class BoxProgram {
    public static void main(String args[]) {
        Box myBox1 = new Box();
        Box myBox2 = new Box();
        double vol;
        myBox1.dimensions(10,20,15); 
        myBox1.dimensions(3, 6, 9); 
        vol = myBox1.volume();
        System.out.println("Volume: " + vol);
        vol = myBox2.volume();
        System.out.println("Volume: " + vol);
    }
}
```
  1. Constructor in Java

    It initializes an object immediately upon creation. The constructor is called when an object of a class is created. It can be used to set initial values for object attributes.

    How Constructors are Different From Methods in Java?

    • Constructors must have the same name as the class within which it is defined it is not necessary for the method in Java.

    • Constructors do not return any type while method(s) have the return type or void if does not return any value.

    • Constructors are called only once at the time of Object creation while method(s) can be called any number of times.

      (a)

```java
class Box {
    double width, height, depth; //instance var
    Box() {//constructor
        width = 10;
        height = 10;
        depth = 10;        
    }
    double volume() { //method
        return width * height * depth;
    }
}
class BoxProgram {
    public static void main(String args[]) {
        Box myBox1 = new Box();
        Box myBox2 = new Box();
        double vol;
        vol = myBox1.volume();
        System.out.println("Volume: " + vol);
        vol = myBox2.volume();
        System.out.println("Volume: " + vol);
    }
}
```

> output:
> 
> Volume: 1000.0
> 
> Volume: 1000.0

(b) Parameterized Constructor

```java
class Box {
    double width, height, depth; //instance var
    Box(double w, double h, double d) {
        width = w;
        height = h;
        depth = d;        
    }
    double volume() { //method
        return width * height * depth;
    }
}
class BoxProgram {
    public static void main(String args[]) {
        Box myBox1 = new Box(10, 20, 15);
        Box myBox2 = new Box(3, 6, 9);
        double vol;
        vol = myBox1.volume();
        System.out.println("Volume: " + vol);
        vol = myBox2.volume();
        System.out.println("Volume: " + vol);
    }
}
```

> output:
> 
> Volume: 3000.0
> 
> Volume: 162.0
  1. Garbage Collection

    If a variable is initialized but not assigned. Garbage collection will deallocate them/ remove them to clear up the memory.

  2. finalize() method

    It is a method that is used to perform clear up activity, before being destroyed by the garbage collector from memory. It is called for every object.

  3. Stack

    • It stores data in first-in-last-out order.

      eg: a stack of plates on the table.

    • two operations that control stack:

      push - to push an item on top of the stack.

      pop - to take an item out of the stack.

  4. Overloading method

    Two or more methods within the same class, same method name but with different parameters.

    class Overloading {
        void test() { //method 1 would be executed when there is no parameter
            System.out.println("none");
        }
        void test(int a) { //method 2 would be executed when there is one parameter
            System.out.println("a: " + a);
        }
    
    }
    class MyClass{
        public static void main(String args[]) {
            Overloaf newO = new Overload();
            newO.test(); //calls method1
            newO.test(10); //calls method1
        }
    }
    
  5. Overloading Constructor

    Overloading in java In addition to overloading methods, we can also overload constructors in java. An overloaded constructor is called based on the parameters specified when new is executed.

    class Box {
        double width, height, depth;
        // constructor used when all dimensions specified
        Box(double w, double h, double d) {
            width = w;
            height = h;
            depth = d;
        }
        // constructor used when no dimensions specified
        Box() {
            width = height = depth = 0;
        }
        // constructor used when cube is created
        Box(double len) {
            width = height = depth = len;
        }
        // compute and return volume
        double volume() {
            return width * height * depth;
        }
    }
    public class OverloadConstructor {
        public static void main(String args[]) {
            // create boxes using the various constructors
            Box mybox1 = new Box(10, 20, 15);
            Box mybox2 = new Box();
            Box mycube = new Box(7);
            double vol;
            // get volume of first box
            vol = mybox1.volume();
            System.out.println(" Volume of mybox1 is " + vol);
            // get volume of second box
            vol = mybox2.volume();
            System.out.println(" Volume of mybox2 is " + vol);
            // get volume of cube
            vol = mycube.volume();
            System.out.println(" Volume of mycube is " + vol);
        }
    }
    

    output:

    Volume of mybox1 is 3000.0

    Volume of mybox2 is -1.0

    Volume of mycube is 343.0

  6. Recussion

    The process in which a function calls itself directly or indirectly is called recursion.

    int fact(int n)
    {
        if (n < = 1) // base case
            return 1;
        else    
            return n*fact(n-1);    
    }
    

    let us look at the example given below:

    public class Count {
        static int count = 0;
        static void p() {
            count++;
            if(count <=5) {
                System.out.println("Hello " + count);
                p();
            }
        }
        public static void main(String[] args) {
            p();
        }
    }
    

    output:

    Hello 1

    Hello 2

    Hello 3

    Hello 4

    Hello 5

  7. Access Control

    • We know Encapsulation links data with code.

    • It also provides Access Control.

    • You can control which part of the program can access members of the class.

    • Java access modifiers are:

      public - When a member of the class is modified by the public, then that member can be accessed by another code outside the class.

      private - Can Only be accessed by another member of its class.

      protected - Is applied when inheritance is involved.

      default

        int a; //default
        public int b; //public
        private int b; //private
      
  8. Static

    • The static keyword in Java is used to share the same variable or method of a given class. The users can apply static keywords with variables, methods, blocks, and nested classes. The static keyword belongs to the class than an instance of the class. The static keyword is used for a constant variable or a method that is the same for every instance of a class.

    • does not support this or super keyword.

        class Test{
            // static method
            static void m1() {
                System.out.println("from m1");
            }
            public static void main(String[] args) {
                  // calling m1 without creating
                  // any object of class Test
                   m1();
            }
        }
      
> output:
> 
> from m1
  1. Final

    • prevents its content from being modified.

    • they are like constants.

    • written in caps.

        final int VARIABLE_NAME = 1;
      
  2. Nested Class & Inner Class.

    • Class within another class -> Nested class

    • The Inner class has access to the outer class but the other class does not have access to the inner class.

        class Outer {
            int x = 100;
            class Inner {
                System.out.println(x);
            }
        }
      
    • Types of nested classes: static & non-static.

      static - Cannot refer to a non-static member of its enclosing class(Not much used)

    • An inner class is a non-static class: It has access to all variables & members of the outer class.

  3. String Class

    • Every String we create is the object of Strings / String Object

    • Strings are immutable (Once created, cannot be altered) but StringBuffer and StringBuilder allows us to modify strings.

  4. StringBuffer

    StringBuffer is used to create a mutable (modifiable) string.

    Constructors of StringBuffer class

    1. StringBuffer(): It reserves room for 16 characters without reallocation

    StringBuffer s = new StringBuffer();
    

    2. StringBuffer( int size): It accepts an integer argument that explicitly sets the size of the buffer.

    StringBuffer s = new StringBuffer(20);
    

    3. StringBuffer(String str): It accepts a string argument that sets the initial contents of the StringBuffer object and reserves room for 16 more characters without reallocation.

    StringBuffer s = new StringBuffer("GeeksforGeeks");
    

    Methods of StringBuffer class

    | Methods | Action Performed | | --- | --- | | append() | Used to add text at the end of the existing text. | | length() | The length of a StringBuffer can be found by the length( ) method | | capacity() | the total allocated capacity can be found by the capacity( ) method | | charAt() | This method returns the char value in this sequence at the specified index. | | delete() | Deletes a sequence of characters from the invoking object | | deleteCharAt() | Deletes the character at the index specified by the loc | | ensureCapacity() | Ensures capacity is at least equal to the given minimum. | | insert() | Inserts text at the specified index position | | length() | Returns the length of the string | | reverse() | Reverse the characters within a StringBuffer object | | replace() | Replace one set of characters with another set inside a StringBuffer object |

  5. StringBuilder

    StringBuilder class provides an alternative to String Class, as it creates a mutable sequence of characters. The function of StringBuilder is very much similar to the StringBuffer class, as both of them provide an alternative to String Class by making a mutable sequence of characters. However, the StringBuilder class differs from the StringBuffer class based on synchronization. The StringBuilder class provides no guarantee of synchronization whereas the StringBuffer class does. Therefore this class is designed for use as a drop-in replacement for StringBuffer in places where the StringBuffer was being used by a single thread

    Constructors in Java StringBuilder Class

    • StringBuilder(): Constructs a string builder with no characters in it and an initial capacity of 16 characters.

    • StringBuilder(int capacity): Constructs a string builder with no characters in it and an initial capacity specified by the capacity argument.

    • StringBuilder(CharSequence seq): Constructs a string builder that contains the same characters as the specified CharSequence.

    • StringBuilder(String str): Constructs a string builder initialized to the contents of the specified string.

      Methods in Java StringBuilder

      StringBuilder append(X x): This method appends the string representation of the X-type argument to the sequence.

      1. StringBuilder appendCodePoint(int codePoint): This method appends the string representation of the codePoint argument to this sequence.

      2. int capacity(): This method returns the current capacity.

      3. char charAt(int index): This method returns the char value in this sequence at the specified index.

      4. IntStream chars(): This method returns a stream of int zero-extending the char values from this sequence.

      5. int codePointAt(int index): This method returns the character (Unicode code point) at the specified index.

      6. int codePointBefore(int index): This method returns the character (Unicode code point) before the specified index.

      7. int codePointCount(int beginIndex, int endIndex): This method returns the number of Unicode code points in the specified text range of this sequence.

      8. IntStream codePoints(): This method returns a stream of code point values from this sequence.

      9. StringBuilder delete(int start, int end): This method removes the characters in a substring of this sequence.

      10. StringBuilder deleteCharAt(int index): This method removes the char at the specified position in this sequence.

      11. void ensureCapacity(int minimumCapacity): This method ensures that the capacity is at least equal to the specified minimum.

      12. void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): This method characters are copied from this sequence into the destination character array dst.

      13. int indexOf(): This method returns the index within this string of the first occurrence of the specified substring.

      14. StringBuilder insert(int offset, boolean b): This method inserts the string representation of the boolean alternate argument into this sequence.

      15. StringBuilder insert(): This method inserts the string representation of the char argument into this sequence.

      16. int lastIndexOf(): This method returns the index within this string of the last occurrence of the specified substring.

      17. int length(): This method returns the length (character count).

      18. int offsetByCodePoints(int index, int codePointOffset): This method returns the index within this sequence that is offset from the given index by codePointOffset code points.

      19. StringBuilder replace(int start, int end, String str): This method replaces the characters in a substring of this sequence with characters in the specified String.

      20. StringBuilder reverse(): This method causes this character sequence to be replaced by the reverse of the sequence.

      21. void setCharAt(int index, char ch): In this method, the character at the specified index is set to ch.

      22. void setLength(int newLength): This method sets the length of the character sequence.

      23. CharSequence subSequence(int start, int end): This method returns a new character sequence that is a subsequence of this sequence.

      24. String substring(): This method returns a new String that contains a subsequence of characters currently contained in this character sequence.

      25. String toString(): This method returns a string representing the data in this sequence.

      26. void trimToSize(): This method attempts to reduce storage used for the character sequence.

  6. Command line argument

    • Sometimes you want to pass information in a program when you run it. this is accomplished by passing a command-line argument to the main()

    • They are stored as a String array passed to the args parameter of main().

  7. args[0], args[1], ...

    class CommandLine {
        public static void main(String args[]) {
            for(int i=0; i <args.length; i++) {
                System.out.println("args [" +i+ "]: " +args[i]);
            }    
        }
    }
    

    Try to execute this program, as shown below:

    Java CommandLine this is a test

    output:

    args[0]: this

    args[1]: is

    args[2]: a

    args[3]: test

  8. Variable length Argument(Varargs)

    A method that takes a variable number of arguments. A variable-length argument is specified by three periods or dots(…)

    For Example,

    public static void fun(int ... a) 
    {
       // method body
    }
    
    / Java program to demonstrate varargs
    
    class Test1 {
        // A method that takes variable number of integer arguments.
        static void fun(int... a) {
            System.out.println("Number of arguments: " + a.length);
            // using for each loop to display contents of a
            for (int i : a)
                System.out.print(i + " ");
            System.out.println();
        } 
        // Driver code
        public static void main(String args[]) {
            // Calling the varargs method with different number of parameters 
            // one parameter
            fun(100);    
            // four parameters
            fun(1, 2, 3, 4);
            // no parameter
            fun();
        }
    }
    
  9. Inheritance

    Java allows Hierarchical classification using Inheritance. We can create a superclass, whose property could be inherited by the subclass.

    superclass - a class that is inherited.

    subclass - that does the inheriting. It inherits the superclass and adds its element.

    To inherit we simply use extend keyword.

    //Create a superclass
    class A {
        int i;
        void showi() {
            System.out.println("i is " +i);
        }
    }
    //Creat a subclass by extending class A
    class B extends A {
        int j;
        void showj() {
            System.out.println("j is " +j);
        }
        void sum() {
            System.out.println("i + j is " (i+j));
        }
    }
    
    //main class
    class Inheritance {
        public static void main(String args[]) {
            A sup = new A();
            B sub = new B();
            sup.i=5;
            sup.showi();
    
            //subclass will inhert superclass as well as it's own element
            sub.i=10;
            sub.j=15;
            sub.showj();
            sub.sum();
        }
    }
    

    output:

    i is 5

    j is 10

    i + j is 25 // i=10,j=15 from class B

    Note: If a variable in the superclass is PRIVATE, then the subclass cannot inherit it.

  10. Super keyword

    A subclass can call a constructor defined by its superclass by using the super keyword.

    syntax:

    super(arg-list);

    class Box {
        double width, height, depth;
        Box(double w, double h, double d) {
            width = w;
            height = h;
            depth = d;
        }
    // ....
    }
    class BoxWeight extends Box {
        double anotherWeight; //weight of box
        // initialize width, height, depth using super()
        BoxWeight(double w, height h, double d, double m) {
            super(w, h, d); // call superclass constructor
            anotherWeight = m;
        }
    }
    

    The second use of Super

    The second form of super is somewhat like this keyword, it refers to the superclass.

    syntax:

    super.member;

    member can be a method/instance variable;

    class A {    //superclass
        int i;
    }
    class B extends class A {    //subclass
        int i;    // this i hides the i in class A
        B(int a, int b) {
            super.i=a;    // invoking i in class A
            i=b;    // invoking i in class B
        }
    // ...
    }
    
  11. Multilevel Hierarchy

    We can have more than one subclass and superclass.

    If class B extends class A & class C extends class B then class C will inherit both B as well as A.

    Note: subclass inherits all of its superclasses.

    class A {
       void funcA() {
          System.out.println("This is class A");
       }
    }
    class B extends A {
       void funcB() {
          System.out.println("This is class B");
       }
    }
    class C extends B {
       void funcC() {
          System.out.println("This is class C");
       }
    }
    public class Demo {
       public static void main(String args[]) {
          C obj = new C();
          obj.funcA();
          obj.funcB();
          obj.funcC();
       }
    }
    

    Output

    This is class A
    This is class B
    This is class C
    
  12. Method Overriding

    Rules: Same method name, and same parameter, but is present in the parent-child relationship, then we can use method overriding.

    class A {
        int i,j;
        A(int a, int b) {
            i = a;
            j = b;
        }
        void show() {
            System.out.println("i and j: " +i+ " " +j);
        }
    }
    class B extends class A {
        int k;
        B(int a, int b, int c) {
            super(a,b);
            k = c;
        }
        void show() {    // This overrides show() in class A
            System.out.println("k: " +k);
        }
    }
    
    class MethodOverriding {
    // ...
    }
    

    output:

    k: 5

    this can be prevented using the super keyword.

    class A {
        int i,j;
        A(int a, int b) {
            i = a;
            j = b;
        }
        void show() {
            System.out.println("i and j: " +i+ " " +j);
        }
    }
    class B extends class A {
        int k;
        B(int a, int b, int c) {
            super(a,b);
            k = c;
        }
        void show() {    
            super.show();    // This calls show() in class A
            // ...
        }
    }
    
    class MethodOverriding {
    // ...
    }
    
  13. Why Overriden methods

    To support run-time polymorphism.

    • Even though the superclass provides all elements that the subclass can use.

    • It also defines the method that the derived class can implement on its own.

  14. Abstract Class

    • A class that is declared with the abstract keyword is known as an abstract class in Java.

      syntax:

      abstract type-name(parameter);

        abstract class A {
            abstract void callme();    // abstract method is defined here
        }
        class B extends class A {
            void callme() {    //The above method is implemented here
                System.out.println("B is implemented");
            }
        }
        // ...
        //output:
        B is implemented
      
  15. Use of final keyword to prevent Overriding

    class A {
        final void math() {
            // This will be executed
        }
    }
    
    class B extends class A {
        void math() {
            // error can't override class A because of 'final' keyword.
        }
    }
    
  16. Use of final keyword to prevent inheritance

    final class A {
        // This will be executed
    }
    
    class B extends class A {
        // error can't override class A because of 'final' keyword.
    }
    
  17. Package

    • To avoid a collision the class name should be unique. The package is a naming & visibility control mechanism.

    • When we define a class inside the package, that would not be accessible by code outside the package.

    • Only exposed to other members of the same package.

      Syntax:

      package Package_name;

        package java.awt.image;
      
    • Needs to store in the same location as mentioned. i.e. java/awt/image

    • If you want to change the name of the package, then the directory should be renamed as well.

  18. Finding package

    • Create a folder MyPack and inside it create a file Accounts.java

    • Write some code inside Accounts.

        //sample program
        package MyPack;
        class Accounts { 
            //... 
        }
      
    • Next compile file [NOTE: class should be inside MyPack]

    • Run in terminal: java MyPack.Accounts

  19. Importing package

    eg: Write this in the top of the java file to import Date.

    import java.util.Date;

  20. Interface

    • An interface in Java is a blueprint of a class. It has static constants and abstract methods.

    • The interface in Java is a mechanism to achieve abstraction. There can be only abstract methods in the Java interface, not the method body. It is used to achieve abstraction and multiple inheritances in Java.

    • In other words, you can say that interfaces can have abstract methods and variables. It cannot have a method body.

      Defining an interface

      access interface_name {

      return-type method-name (parameter);

      type final_variable = value;

      }

        interface printable{  
        void print();  
        }  
        class A6 implements printable{  
        public void print(){System.out.println("Hello");}  
      
        public static void main(String args[]){  
        A6 obj = new A6();  
        obj.print();  
         }  
        }  
        //output:
        //Hello
      
  21. Exception Handling

    • The exception is created and thrown in a method that causes the error.

    • Could be generated manually by code or by Java run-time.

    • Managed by try, catch, throw, throws and finally.

  22. Try & Catch

    Try - contains code you want to monitor.

    Catch - Specifies the exception type you wish to catch.

    // Syntax
    try {
      //  Block of code to try
    }
    catch(Exception e) {
      //  Block of code to handle errors
    }
    
    //If an error occurs, we can use try...catch to catch the error and execute some code to handle it:
    public class Main {
      public static void main(String[ ] args) {
        try {
          int[] myNumbers = {1, 2, 3};
          System.out.println(myNumbers[10]);
        } catch (Exception e) {
          System.out.println("Something went wrong.");
        }
      }
    }
    // The output will be:
    Something went wrong.
    
    • There can be multiple catch statements.

    • There can be nested try statements.

  23. Throw

    When the try block is inspected and no catch statement is matched, then we print the throw statement.

    // Syntax: 
    throw Instance
    // Example:
    throw new ArithmeticException("/ by zero");
    // The code will look something like this
    try {
        throw ...;
    } catch(... e) {
        throw e; // rethrowing the exception
    }
    
  24. Throws

    If a method is capable of causing exception that it does not handle, we can use throws.

    // form
    type method_name(parameter) throws exception_list {
        // ....
    }
    // exception_list is a comma separated list of all the exceptions which a method might throw.
    
  25. Finally

    • we will create a block of code that will be executed after the try/catch block.

    • If an exception is thrown, finally will be executed even if no catch statement matches.

        try{    
        //If code do not throw any exception     
          catch(... e){  
            //catch won't be executed
        }    
        finally {  
            //executed regardless of exception occurred or not  
        }
      
  26. Multithreading

    • A multithreaded program contains two or more parts that can run concurrently.

    • Each part is called a thread, each thread defines separate execution.

  27. Deadlock

    • a special type of error in multitasking.

    • Occur when two threads have a circular dependency on pair of synchronized object.

      • eg: thread enters object X and another thread enters object Y

      • If thread X calls the Synchronization method on Y it will block as expected.

      • If thread Y in return calls the Synchronization method on X, the thread will wait forever.

      • because to access X, it would have to release its own lock on Y. So that the first thread could be completed.

      • Such a situation is called a Deadlock.

    • It occurs only rarely.

    • It can invoke more than two thread

  28. Synchronization

    • Synchronization in Java is the capability to control the access of multiple threads to any shared resource.

    • Java Synchronization is a better option where we want to allow only one thread to access the shared resource.

Hope this covered every Nook and corner in Java.
Follow for more such blogs.