Oct 10th, 2012


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);
  • 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.


  • 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”.


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.

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

Stream API

java stream group by date monthly

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