DEV Community

Cover image for Revisiting Java (Again) in a Weekend
Sudipto Ghosh
Sudipto Ghosh

Posted on • Originally published at blog.ghosh.pro

Revisiting Java (Again) in a Weekend

I landed in the Java universe again, after evolving through a few JavaScript frameworks and a bit of C++ and a ton of Python. I had given up on Java sometime in the past and I don't really know why.

The Basics

The Java Buzzwords

  • Simple
  • Secure
  • Portable
  • Object-oriented
  • Robust
  • Multithreaded
  • Architecture-neutral
  • Interpreted
  • High performance
  • Distributed
  • Dynamic

Setting up the Environment

Installing Java

I used the Java SE Development Kit (JDK) 8 (developer version 1.8) by Oracle. OpenJDK is the same sans proprietary issues. Once past that, I set the environment variables JAVA_HOME and PATH to point to the directories where the binaries of the Java toolchain reside.

Code Editor v/s IDE

Personal Preference. VS Code as an editor and IntelliJ IDEA as an IDE are great choices. I use both 😁

Verification

Executing java -version && javac -version outputs whatever is given below:

$ java -version && javac -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
javac 1.8.0_231
Enter fullscreen mode Exit fullscreen mode

Bytecode Stuff

Overview

Here's a flowchart!

The  Flowchart

Compilation

I wrote text file with a .java extension containing some lines of code and compilde it to Java Bytecode with the javac compiler. Compilation resulted in a binary .class file that will be used for interpretation.

Interpretation

The .class file is loaded to the Java Virtual Machine using a Class Loader in the JVM. The .class files are vulnerable and using a hex editor, an attacker can change the behaviour of a program. To overcome this issue, the bytecode is then verified using the Bytecode Verifier in the JVM. The Java Just-In-Time (JIT) Compiler or Runtime Interpreter then interprets the bytecode and produces machine code depending on the system architecture which can then be loaded into memory for execution.

The Code

Here's how a "Hello, World!" would look like in Java. Classes, I know, yes, there is some overhead involved but walk along. And yes, it is a little verbose.

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
Enter fullscreen mode Exit fullscreen mode

But I should add comments! So the final source code could be something like:

// HelloWorld.java

/**
 * Hello World Application
 * @author sudipto@ghosh.pro
 */

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
Enter fullscreen mode Exit fullscreen mode

To compile my HelloWorld.java file to bytecode, I ran the javac compiler with a CLI argument.

$ javac HelloWorld.java 
Enter fullscreen mode Exit fullscreen mode

This created a HelloWorld.class file in the same directory. Opening it in a text editor was not of much use as it is a binary file but you can surely see a few symbols here and there.

����4↔
♠☼      ►↕
‼¶§▬☺♠<init>☺♥()V☺♦Code☺☼LineNumberTable☺♦main☺▬([Ljava/lang/String;)V☺
SourceFile☺☼HelloWorld.java↨♀↑↓☺
Hello, World!→♀∟☺
elloWorld☺►java/lang/Object☺►java/lang/System☺♥out☺§Ljava/io/PrintStream;☺‼java/io/PrintStream☺println☺§(Ljava/lang/String;)V!♣♠☻☺      ↔☺☺♣*�☺�☺
♠☺♠     ♂♀☺     %☻☺     �☻↕♥�♦�☺

☻       ☺
☻♫
Enter fullscreen mode Exit fullscreen mode

Using the Java Class File Disassembler, we can see some interpreted assembly code. To view that, I used the javap tool in the JDK. Running javap -c HelloWorld outputted some code which also points to the fact that if there is no default constructor, the compiler puts it there!

$ javap -c HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1     // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2     // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3     // String Hello, World!
       5: invokevirtual #4     // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}
Enter fullscreen mode Exit fullscreen mode

To load my HelloWorld.class into the JVM and execute it, I invoked java with a command-line argument that matches the base name of the .class file.

$ java HelloWorld
Enter fullscreen mode Exit fullscreen mode

Once this command was executed, the message Hello, World! correctly printed onto the screen, technically console.

Learning Resources

I referred to Java: The Complete Reference (9th ed.) by Herbert Schildt and the Oracle documentation for getting around the intricacies of the language.

Project 01: Text Editor

A basic text editor that can open and save text files. It also features a word counter and character counter. Learnt about StringTokenizer, FileReader, FileWriter, BufferredReader, BufferredWriter and StringBuilder. The GUI was designed with Swing and the IntelliJ IDEA GUI Designer.

Demonstration

Code

https://github.com/sudiptog81/ducscode/tree/master/Year%20I/Semester%20II/Java/Other/27-12-2019/notepadClone/

Project 02: Store Management System

Used the SQLite JDBC Driver to interface with a database and manage customers, inventory items and process orders of a dummy store. The GUI was designed with Swing and the IntelliJ IDEA GUI Designer. Had to struggle a bit with JTable but figured it out at last.

Demonstration

Code

https://github.com/sudiptog81/ducscode/tree/master/Year%20I/Semester%20II/Java/Other/28-12-2019/customerManagementSystem/

Bonus

Just received Hacktoberfest 2019 swag. Happy!

The Stuff

Top comments (0)