Java

JVM

JIT In the mid 90s, java changed the world. They’ve introduced things like JIT compilation, garbage collection, portable safe code, memory safe code, dynamic dispatch execution model.

Java is a static language, meaning the a variable once created cannot be changed. If its type has been defined, then only the value of the variable can be changed. Type is static. Different from dynamic languages.

Download Java

I’ve downloaded java 1.8 for the SE465 assignments.

First go to Oracle Java SE 8 Archive Downloads and choose the right version for your laptop. I chose the macOS x64. Download and Install. Then you can find it under /Library/Java/JavaVirtualMachines.

I put those in ~/.zshrc, need to source it to get this version.

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
java -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

I don’t know how to get 1.8.0_221…

Java Questions

Difference between Java and C++:

  • Java doesn’t have virtual function, instead, have similar concept as virtual functions in C++, implemented differently. In java, it’s called “method overriding”.
    • In java, all non-static methods are “virtual” by default, meaning they can be overridden in subclasses. However you don’t explicitly mark methods as virtual as you do in C++. Got it.
    • Instead use @Override comment to indicate that a method in a subclass is intended to override a method in the superclass.
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}
 
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}
 
public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog(); // Polymorphic assignment
        animal.makeSound(); // Calls the overridden method in Dog
    }
}
  • Functionality supported in C++ but not in Java are:
    • goto
    • Pointers
    • Call by reference
    • Structures and Unions
    • Multiple Inheritance
    • Virtual Functions

Types in Java

Two types of data:

  • Primitive Data Type
    • boolean, byte, char, short, int, long, float, double
  • Non-Primitive Data Type or Object Data type: reference data types will contain a memory address of the variable’s values because it is not able to directly store the values in the memory
    • Strings, Array, Class, Object, Interface

Class Variable

In Java, a class variable (also known as a static variable) is a variable that is declared within a class but outside of any method, constructor, or block. Class variables are declared with the static keyword, and they are shared by all instances (objects) of the class as well as by the class itself. No matter how many objects are derived from a class, each class variable would only exist once.

When it says it is shared by all instances of the class, does it mean it is sort of a "global value" for this class?

Yes, when it says that a class variable (static variable) is shared by all instances of the class, it means that the variable is effectively like a global value for that class.

Regardless of how many objects (instances) of the class are created, there’s only one instance of the class variable that exists in memory. All instances of the class share and have access to this single variable.

  • Accessible Without Object Instantiation: Unlike instance variables, which belong to individual objects and require object instantiation to access, class variables can be accessed directly using the class name, without the need to create an instance of the class.
  • Scope: Class variables are accessible from any part of the class where their scope is visible (i.e., within the class where they are defined). They are not tied to a specific instance’s state but rather to the class itself.
  • Common Use Cases: Class variables are often used to store data that is common to all instances of the class, such as constants, configuration parameters, counters, or shared resources.

Note

Class variables are not truly global in the sense that their scope is limited to the class in which they are defined. They are global only within the context of that class and its instances. Additionally, modifying the value of a class variable affects all instances of the class and the class itself, which may lead to unintended consequences if not managed carefully.

Difference between instance variable and a class variable?

  • Instance Variable: A class variable without a static modifier known as an instance variable is typically shared by all instances of the class. These variables can have distinct values among several objects. The contents of an instance variable are completely independent of one object instance from another because they are related to a specific object instance of the class.
  • Class Variable:  Class Variable variable can be declared anywhere at the class level using the keyword static. These variables can only have one value when applied to various objects. These variables can be shared by all class members since they are not connected to any specific object of the class.

Arrays

Arrays are always created on the heap, regardless of how they are declared or used. The heap memory is managed by the Java Virtual Machine (JVM) and it is also shared between all threads of the Java Program.

data_type[] Array_Name = new data_type[ArraySize];

Difference between int array[] and int[] array?

  • No difference in terms of functionality, just different ways of declaring.

OOPs

Main concept of OOP in Java:

  • Inheritance
  • Polymorphism
  • Abstraction
  • Encapsulation

Access Specifiers

  • Public
  • Private
  • Protected
  • Default

Object

The object is defined to be an instance of a class. An object can be declared using a new keyword.

Methods to create objects in Java are mentioned below:

  1. Using new keyword
  2. Using new instance
  3. Using clone() method
  4. Using deserialization
  5. Using the newInstance() method of the Constructor class

Constructor

A special method used to initialize objects. The constructor is called when a object is created. Name of constructor is same as of the class.

// Class Created
class XYZ {
	private int val;
 
	// Constructor
	XYZ(){
		val = 0;
	}
};

If you don’t provide a constructor in a class in Java, the compiler automatically generates a default constructor with no arguments and no operation which is a default constructor.

Two types of constructors:

  • Default constructor: does not accept any parameter value. used to set initial values for object attributes
  • Parameterized constructor: accepts parameters as arguments. These are used to assign values to instance variables during the initialization of objects

Constructors are used to help create instance of a class or can be said to create objects of a class. It is called during the initialization of objects.

Copy Constructor

A copy constructor in Java is a constructor that creates a new object by copying the state of an existing object of the same class. It’s used to create a new object with the same data as an existing object. Unlike other constructors, a copy constructor takes an instance of the same class as its parameter.

public class MyClass {
	private int data;
 
	public MyClass(int data) {
		this.data = data
	}
 
	public MyClass(MyClass other){
		this.data = other.data;
	}
 
	...
};

Where and how can you use a private constructor?

  • A private constructor is used if you don’t want any other class to instantiate the object to avoid subclassing.
  • I don’t really understand.
  • Example: Singleton Pattern: A singleton class ensures that only one instance of the class is created. This is achieved by having a private constructor and providing a static method to access the single instance.

Interface

What is an interface?

  • An interface in Java is a collection of static final variables and abstract methods that define the contract or agreement for a set of linked classes. Any class that implements an interface is required to implement a specific set of methods. It specifies the behaviour that a class must exhibit but not the specifics of how it should be implemented.
import java.io.*;
 
interface Shape {
	double getArea();
	double getPerimeter();
}
 
class Circle implements Shape {
	private double radius;
	public Circle(double radius) { this.radius = radius; }
 
	public double getArea(){
		return Math.PI * radius * radius;
	}
 
	public double getPerimeter() {
		return 2 * Math.PI * radius;
	}
}
interface Animal {
    void makeSound();
}
 
class Dog implements Animal {
    public void makeSound() {
        System.out.println("Woof");
    }
}
 
class Cat implements Animal {
    public void makeSound() {
        System.out.println("Meow");
    }
}
 
public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
 
        dog.makeSound(); // Output: Woof
        cat.makeSound(); // Output: Meow
    }
}

The main() method demonstrates polymorphism by creating instances of Dog and Cat through the Animal reference and calling the makeSound() method, which executes the respective implementations in each class.

What are some features of the Interface?

  • Achieve total abstraction
    • leave the implementation to the different class
    • details of implementation are hidden from the users of the interface
  • Allows us to use multiple inheritances in Java
    • unlike abstract classes, interface allows you to achieve multiple inheritance
    • This allows a class to inherit method signatures and constants from multiple interfaces, enabling it to exhibit behaviours defined by different interfaces.
    • Any class can implement multiple interfaces even when one class can extend only one class.
  • It is also used to achieve loose coupling
    • Loose coupling refers to reducing the dependencies between components of a system.
    • By programming to interfaces rather than concrete implementations, classes become less dependent on each other, making the code more modular, maintainable, and easier to change.
    • Interfaces provide a contract or agreement between different components, allowing them to interact based on common behaviours rather than specific implementations.
    • If you decide to add more shapes in the future, you can simply create new classes that implement the Shape interface without modifying the Main class.

Differences between abstract class and interface?

Encapsulation

The main advantage of Encapsulation in Java is its ability to protect the internal state of an object from external modification or access. It is the is a way of hiding the implementation details of a class from outside access and only exposing a public interface that can be used to interact with the class. The main benefit is of providing a way to control and manage the state and the behaviour of an object and also protecting it from modification and unauthorized access at the same time.

  • Declare data members (fields) of a class to be private, preventing external access.
  • Hide implementation by encapsulating internal state of class. Makes it easier to understand and use because users only need to know how to interact with the class through public interface. Don’t need to understand how it is implemented.

Examples: getters and setters

public class Person {
    private String name;
    private int age;
 
    // Getter and setter methods to access and modify the private fields
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        if (age >= 0) { // Validation to ensure age is non-negative
            this.age = age;
        }
    }
}

In this example, the Person class encapsulates its internal state (name and age) by making the fields private. The only way to access or modify these fields is through getter and setter methods, which provide controlled access to the class’s state. This allows the class to enforce any necessary validations or business rules, such as ensuring the age is non-negative.

Inheritance

Inheritance is the method by which the Child class can inherit the features of the Super or Parent class. In Java, Inheritance is of four types:

  • Single Inheritance: When a child or subclass extends only one superclass, it is known to be single inheritance. Single-parent class properties are passed down to the child class. 
  • Multilevel Inheritance: When a child or subclass extends any other subclass a hierarchy of inheritance is created which is known as multilevel inheritance. In other words, one subclass becomes the parent class of another.
  • Hierarchical Inheritance: When multiple subclasses derive from the same parent class is known as Hierarchical Inheritance. In other words, a class that has a single parent has many subclasses.
  • Multiple Inheritance: When a child class inherits from multiple parent classes is known as Multiple Inheritance. In Java, it only supports multiple inheritance of interfaces, not classes.