Java

Oct 10th, 2012

Installation

Get all java versions installed in your machine:

/usr/libexec/java_home -V

To install the latest or the specific version

brew install openjdk
brew install openjdk@11
brew install openjdk@17

For the system Java wrappers to find this JDK, symlink it with

sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
sudo ln -sfn /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
sudo ln -sfn /usr/local/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk

If you need to have openjdk@17 first in your PATH, run:

echo 'export PATH="/usr/local/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc

or edit .zshrcfile add below line

export JAVA_HOME=/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home

Attributes and Methods

public class TestClass {
    private final String param4 = "4";
    private final int param5 = 5;
    public String test(String param1, int param2, int param3) {
      return param1 + (param2 + param3 + param4);
    }
    
    public static void main(String args[]) {
        TestClass testClass = new TestClass();
        String output = testClass.test("test", 1, 2);
        System.out.println(output);
    }
}
  • Function => param1, param2, param3 -> Parameters (Placeholder, formal parameters)
  • Method => param1, param2, param3 -> Arguments (Placeholder, formal parameters)
  • param4, param5 -> Attributes, Fields (Class Attributes)
  • testClass.test("test", 1, 2); “test”, 1, 2 -> Arguments (Actual value, actual parameters) It returns test345.

Modifiers

  • Access Modifiers - controls the access level.
  • Non-Access Modifiers - do not control access level, but provides other functionality.

Access Modifiers

For classes, you can use either public or default:

  • public - The class is accessible by any other class.
  • default - The class is only accessible by classes in the same package. This is used when you don’t specify a modifier.

For attributes, methods and constructors, you can use the one of the following:

  • public - The code is accessible for all classes.
  • private - The code is only accessible within the declared class.
  • default - The code is only accessible in the same package. This is used when you don’t specify a modifier.
  • protected - The code is accessible in the same package and subclasses.

Non-Access Modifiers

For classes, you can use either final or abstract:

  • final - The class cannot be inherited by other classes.
  • abstract - The class cannot be used to create objects (To access an abstract class, it must be inherited from another class.)

For attributes and methods, you can use the one of the following:

  • final - Attributes and methods cannot be overridden/modified.
  • static - Attributes and methods belongs to the class, rather than an object.
  • abstract - Can only be used in an abstract class, and can only be used on methods. The method does not have a body, for example abstract void run();. The body is provided by the subclass (inherited from).
  • transient - Attributes and methods are skipped when serializing the object containing them.
  • synchronized - Methods can only be accessed by one thread at a time.
  • volatile - The value of an attribute is not cached thread-locally, and is always read from the “main memory”.

Primitives

Type Size Default
byte 8 bits 0
short 16 bits 0
int 32 bits 0
long 64 bits 0
float 32 bits 0.0f
double 64 bits 0.0d
char 16 bits ‘\u0000’
boolean 1 bit false

Collections in Java

How to choose which collection class to use in java

Embedded web server

Java 18 has arrived with a small embedded web server that only serves static files in the directory in which it is launched. JDK’s bin directory has now a command jwebserver that launches it.

jwebserver
java -m jdk.httpserver -p 8080 -d /tmp/java

Stream API

java stream group by date monthly

Map<YearMonth, Integer> caloriesByMonth = meals.stream()
        .collect(Collectors.groupingBy(m -> YearMonth.from(m.mealtime),
                                       TreeMap::new,
                                       Collectors.summingInt(m -> m.calories)));

Java OOP Concepts

Inheritance

  • Inheritance is used to inherit properties from parent class to child class.
  • Using inheritance, you can reuse existed tried and tested code.
  • Using inheritance, you can also add more features to existing class without modifying it by extending it through its subclass.
  • In Java, inheritance is implemented by using extends keyword.

An example:

class SuperClass
{
  String superClassField = "Super_Class_Field";

  void superClassMethod()
  {
    System.out.println("Super_Class_Method");
  }
}
class SubClass extends SuperClass
{
  String subClassField = "Sub_Class_Field";

  void subClassMethod()
  {
    System.out.println("Sub_Class_Method");
  }
}
public class JavaOOPConcepts
{
  public static void main(String[] args)
  {
    SubClass subClass = new SubClass();
    
    subClass.subClassMethod();
    System.out.println(subClass.subClassField);

    //SuperClass properties are inherited to SubClass
    
    subClass.superClassMethod();
    System.out.println(subClass.subClassField);
  }
}

Abstraction

  • Abstraction means seperating ideas from their actual implementations.
  • Using abstraction, you define only ideas in one class so that those ideas can be implemented by its subclasses according to their requirements.
  • In Java, abstraction is implemented by abstract classes and interfaces.

An abstract class example:

abstract class AbstractClass
{
  abstract void anidea();
}
class SubClassOne extends AbstractClass
{
  @Override
  void anidea()
  {
    System.out.println("An idea is implemented according to SubClassOne requirement");
  }
}
class SubClassTwo extends AbstractClass
{
  @Override
  void anidea()
  {
    System.out.println("An idea is implemented according to SubClassTwo requirement");
  }
}

An interface example:

interface Interface
{
  void anidea();
}
class ClassOne implements Interface
{
  @Override
  public void anidea()
  {
    System.out.println("An idea is implemented according to ClassOne requirement");
  }
}
class ClassTwo implements Interface
{
  @Override
  public void anidea()
  {
    System.out.println("An idea is implemented according to ClassTwo requirement");
  }
}

Polymorphism

  • Poly means many and morphs means forms. So, anything which has multiple forms is called as polymorphism.
  • Any entity like operator or method or constructor which takes many forms and can be used for multiple tasks is called as polymorphism.
  • For example, + operator can be used for addition of two numbers as well as for concatenation of two strings.
  • In Java, there are two types of polymorphism - static polymorphism and dynamic polymorphism.
  • Any entity which show polymorphism during compilation is called static polymorphism.
  • Operator overloading, method overloading and constructor overloading are best examples of static polymorphism.
class AnyClass
{
  int i;
  String s;

  //Constructor Overloading

  public AnyClass()
  {
    this.i = 1;
    this.s = "";
  }

  publci AnyClass(int i, String s)
  {
    this.i = i;
    this.s = s;
  }

  //Method Overloading

  void anyMethod(int i)
  {
    System.out.println(i + this.i); //Here '+' is used to add two numbers
  }

  void anyMethod(String s)
  {
    System.out.println(s + this.s); //Here '+' is used to concatenate two strings
  }
}
  • Any entity which shows polymorphism at run time is called as dynamic polymorphism.
  • Method overriding is the best example of dynamic polymorphism.
class SuperClass
{
  void superClassMethod()
  {
    System.out.println("Super_Class_Method");
  }
}

class SubClass extends SuperClass
{
  @Override
  void superClassMethod()
  {
    System.out.println("Super_Class_Method_Is_Overridden");
  }
}

public class JavaOOPConcepts
{
  public static void main(String[] args)
  {
    SuperClass superClass = new SuperClass();
    
    superClass.superClassMethod(); //Output: Super_Class_Method
    
    superClass = new SubClass();

    superClass.superClassMethod(); //Output: Super_Class_Method_Is_Overridden
  }
}

Encapsulation

  • Bundling of data and operations to be performed on that data into single unit is called as encapsulation.
  • Encapsulation in Java can be achieved by including both variables (data) and methods (operations) which act upon those variables into a single unit called class.
  • Encapsulation is often used to hide important information from outside the world. It is called data hiding. This can be achieved by declaring all important variables as private and providing public getter and setter methods.
class Customer
{
  private int custID;
  private String name;
  private Stirng address;

  //Getter and setter for custID

  public int getCustID()
  {
    return custID;
  }

  public void setCustID(int custID)
  {
    this.custID = custID;
  }

  //Getter and setter for name

  public String getName()
  {
    return name;
  }

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

  //Getter and setter for address

  public String getAddress()
  {
    return address;
  }

  public void setAddress(String address)
  {
    this.address = address;
  }
}

Color with RGBA

Color c = new Color(0b11111111111111111111111111111111, true);

As per the Java docs, the alpha component is in bits 24-31, the red component is in bits 16-23, the green component is in bits 8-15, and the blue component is in bits 0-7.