Week with Java
On 1995-05-23 we got Java 1.0_alpha. 30 years later I got to help with security audit of Java codebase, solidifying my thoughts on this language. I've knew Java for a few years now but there is nothing like a week of staring at someone else's code to evaluate your opinions.
My main takeaway is reinforcement of my love for immutability marking. I dare to say it, it's one of main features that I love about languages like C, C++, Rust, Go and Haskell. Language with implicit reference semantics lack proper notation for (deep) immutability, which makes any reasoning about the codebase at least twice as hard as it should be.
Languages like Java (with final var
) or JavaScript (with const
) have this weird construction that prevents one to reassign variable inside a function body.
While useful for global context (in JavaScript) and useful for class instance context (in Java) it's still only a part of needed solution.
Arguing for immutability feels somewhat outdated - we are few years after the functional programming craze of late 2010s.
What do you mean that there isn't isPositive()
for java.time.Duration
?!
Java Virtual Machine
Going back to Java reignited my interested in what's going under the hood. Beeing one of the oldest commonly used virtual machines out there (beaten only by Erlang I think) it has few interesting quirks and features. I'm exploring it in one of my projects - a Java dissasembler (I don't remember why it's called Hava - name suggests Java but in Haskell but it's written in Rust).
- Function signatures are just strings with special syntax within them.
- There are special opcodes for loading first, second, third and fourth local variables. Other local variables are loaded by general load local variable instruction that embeds an integer.
- You cannot reference variables dynamically (like in C by taking address of a variable). In the bytecode the concept of lvalue doesn't exists.
- Java has only 8 types in the bytecode: byte, char (UTF-16 code point), float, double, short, int, long, reference
javac
is generally not a optimizing compiler. It has some very basic techniques like constant folding but only for expressions. From what I've seen things like unused variables or inlinling arithmetic across variables are not optimized out even when they don't have side effects. Note that this is just bytecode optimization - JIT compiler that would compile this code on target machine possibly has a lot of various optimizations.- class format is optimized for interning, possibly reducing final size - for example if two methods have the same signature then it can be shared between them.