Primitive Data Types

Ref: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

byte: The byte data type is an 8-bit signed two’s complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable’s range is limited can serve as a form of documentation.

short: The short data type is a 16-bit signed two’s complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As with byte, the same guidelines apply: you can use a short to save memory in large arrays, in situations where the memory savings actually matters.

int: By default, the int data type is a 32-bit signed two’s complement integer, which has a minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1. Use the Integer class to use int data type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.

long: The long data type is a 64-bit two’s complement integer. The signed long has a minimum value of -263 and a maximum value of 263-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.

float: The float data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. As with the recommendations for byte and short, use a float (instead of double) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use the java.math.BigDecimal class instead. Numbers and Strings covers BigDecimal and other useful classes provided by the Java platform.

double: The double data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency.

boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its “size” isn’t something that’s precisely defined.

char: The char data type is a single 16-bit Unicode character. It has a minimum value of ‘\u0000’ (or 0) and a maximum value of ‘\uffff’ (or 65,535 inclusive).

Error Handling in Java(Exceptions in Java)

Normal one:

try{
    // your logic
} catch(Exception e) {
    System.out.println(e.getMessage());
}

NumberFormatException: Thrown to indicate that the application has attempted to convert a string to one of the numeric types, but that the string does not have the appropriate format.

try{
    // your logic
} catch(Exception e) {
    System.out.println(e.getMessage());
} catch(NumberFormatException e) {
    System.out.println(e.getMessage());
}

ArithmeticException: Thrown when an exceptional arithmetic condition has occurred. For example, an integer “divide by zero” throws an instance of this class.

try{
    // your logic
} catch(Exception e) {
    System.out.println(e.getMessage());
} catch(NumberFormatException e) {
    System.out.println(e.getMessage());
}catch(ArithmeticException e) {
    System.out.println(e.getMessage());
}

ArrayIndexOutOfBoundsException: Thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.

    try{
        // your logic
    } catch(ArrayIndexOutOfBoundsException e) {
        System.out.println(e.getMessage());
    }

finally: will always run

    try{
        // your logic
    } catch(ArrayIndexOutOfBoundsException e) {
        System.out.println(e.getMessage());
    } finally {
        //always run. e.g. disconnect database.
    }

Java Interface Class

An interface is a completely “abstract class” that is used to group related methods with empty bodies:

interface Animal {
  public void animalSound(); // interface method (does not have a body)
  public void run(); // interface method (does not have a body)
}

To access the interface methods, the interface must be “implemented” (kinda like inherited) by another class with the implements keyword (instead of extends). The body of the interface method is provided by the “implement” class:

// Interface
interface Animal {
  public void animalSound(); // interface method (does not have a body)
  public void sleep(); // interface method (does not have a body)
}

// Pig "implements" the Animal interface
class Pig implements Animal {
  @Override
  public void animalSound() {
    // The body of animalSound() is provided here
    System.out.println("The pig says: wee wee");
  }
  @Override
  public void sleep() {
    // The body of sleep() is provided here
    System.out.println("Zzz");
  }
}

class MyMainClass {
  public static void main(String[] args) {
    Pig myPig = new Pig();  // Create a Pig object
    myPig.animalSound();
    myPig.sleep();
  }
}

Notes on Interfaces:

  • Like abstract classes, interfaces cannot be used to create objects (in the example above, it is not possible to create an “Animal” object in the MyMainClass)
  • Interface methods do not have a body - the body is provided by the “implement” class
  • On implementation of an interface, you must override all of its methods
  • Interface methods are by default abstract and public
  • Interface attributes are by default public, static and final
  • An interface cannot contain a constructor (as it cannot be used to create objects)

Why And When To Use Interfaces?

  1. To achieve security - hide certain details and only show the important details of an object (interface).

  2. Java does not support “multiple inheritance” (a class can only inherit from one superclass). However, it can be achieved with interfaces, because the class can implement multiple interfaces. Note: To implement multiple interfaces, separate them with a comma (see example below).

     interface FirstInterface {
       public void myMethod(); // interface method
     }
        
     interface SecondInterface {
       public void myOtherMethod(); // interface method
     }
        
     class DemoClass implements FirstInterface, SecondInterface {
       public void myMethod() {
         System.out.println("Some text..");
       }
       public void myOtherMethod() {
         System.out.println("Some other text...");
       }
     }
    

Enums

An enum is a special “class” that represents a group of constants (unchangeable variables, like final variables).

To create an enum, use the enum keyword (instead of class or interface), and separate the constants with a comma. Note that they should be in uppercase letters:

enum Level {
  LOW,
  MEDIUM,
  HIGH
}

Read/Write File

There are so many ways to read and write files. Reading and Writing Files in Java.

String directory = System.getProperty("user.home");
String fileName = "sample.txt";
String absolutePath = directory + File.separator + fileName;

// Write the content in file 
try(FileWriter fileWriter = new FileWriter(absolutePath)) {
    String fileContent = "This is a sample text.";
    fileWriter.write(fileContent);
    fileWriter.close();
} catch (IOException e) {
    // Cxception handling
}

// Read the content from file
try(FileReader fileReader = new FileReader(absolutePath)) {
    int ch = fileReader.read();
    while(ch != -1) {
        System.out.print((char)ch);
        fileReader.close();
    }
} catch (FileNotFoundException e) {
    // Exception handling
} catch (IOException e) {
    // Exception handling
}

Static and final

Ref: https://stackoverflow.com/questions/13772827/difference-between-static-and-final

The static keyword can be used in 4 scenarios

  • static variables
  • static methods
  • static blocks of code
  • static nested class

Static variable

  • It is a variable which belongs to the class and not to object (instance).
  • Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
  • A single copy to be shared by all instances of the class.
  • A static variable can be accessed directly by the class name and doesn’t need any object.
  • Syntax: Class.variable

Static method

  • It is a method which belongs to the class and not to the object (instance).
  • A static method can access only static data. It can not access non-static data (instance variables) unless it has/creates an instance of the class.
  • A static method can call only other static methods and can not call a non-static method from it unless it has/creates an instance of the class.
  • A static method can be accessed directly by the class name and doesn’t need any object.
  • Syntax: Class.methodName()
  • A static method cannot refer to this or super keywords in anyway.

Static class

Java also has “static nested classes”. A static nested class is just one which doesn’t implicitly have a reference to an instance of the outer class.

Static nested classes can have instance methods and static methods.

There’s no such thing as a top-level static class in Java.

main method is static since it must be be accessible for an application to run before any instantiation takes place.

final keyword is used in several different contexts to define an entity which cannot later be changed.

  • A final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final.
  • A final method can’t be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.
  • A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a blank final variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.

Shallow copy and deep copy

Ref: https://dzone.com/articles/java-copy-shallow-vs-deep-in-which-you-will-swim

A shallow copy of an object copies the ‘main’ object, but doesn’t copy the inner objects. The ‘inner objects’ are shared between the original object and its copy.

Unlike the shallow copy, a deep copy is a fully independent copy of an object. If we copied our Person object, we would copy the entire object structure.