The Key Differences Between Java and JavaScript

Learning Java can be a painful process if your coming from a JavaScript background. Not only is Java statically typed, it also runs on a completely different environment. While the two languages are fundamentally different, the coding principles are transferable. This tutorial explains the key differences between Java and JavaScript and provides examples of how to do what you already know in JavaScript the Java way.

Running Code: Interpreted vs Compiled Languages

Running your JavaScript code is pretty straightforward. You write some JS and the browser reads it at runtime. Whenever a client loads your webpage or app, the browser evaluates the code in real time. For this reason, JavaScript is considered an interpreted language.

Unfortunately not all languages are interpreted like JavaScript. Many lower level languages (like Java) are compiled languages. This means that any code you write is first compiled into a lower level machine code before it can be executed by the runtime environment.

script.js

console.log('Hello world');

HelloWorld.java

public class HelloWorld {
  public static void main(String[] args) {
    // Prints "Hello, World" to the terminal window.
    System.out.println("Hello world");
  }
}

In the above examples, both script.js and HelloWorld.java print "Hello world" to the console. By simply including our script.js file in an HTML doc, we can run the JavaScript in the browser. With Java, we must first compile our HelloWorld.java class before we can run it in the Java virtual machine (JVM).

NOTE: Most Java IDEs compile things for you when you run them, but you can also run javac HelloWorld.java from the command line to compile your class. This command will produce a compiled HelloWorld.class file that you can then execute with java HelloWorld.

Different Environments: Web Browsers vs JVM

Our JavaScript code runs in the browser while our Java code runs on the Java virtual machine (JVM). For any Java code you write, the JVM acts as the browser. It is the engine that your code runs on. The Java code you write gets compiled into Java bytecode which is then read by the JVM.

Defining Variables

Since JavaScript is an interpreted language, it is also dynamically typed. This means type checking occurs at runtime.

What is type checking?

Type checking is a process where the runtime engine checks defined variables and functions to make sure variables match their expected usage. You don't really worry about this with JavaScript as the browser checks things on the fly.

Java is a different story. Java is statically typed meaning type checking occurs at compile time. The compiler needs to know the data type for each variable before using it. This means your Java code will fail at compile time if data types don't match expectations.

JavaScript

var name = "Sam";

Java

String name = "Sam";

This example illustrates the difference between dynamically and statically typed languages. Notice how with our JavaScript example, we simply assign the string "Sam" to the variable name. It's important to note that we could have assigned anything to our name variable ([], 123, {}).

In our Java example, we have to use the String prefix to explicitly define the name variable as a string. If we try to assign a different data type to our name variable, it will fail at compile time.

What's the point?

Explicitly defining data types is hard to cope with as a JavaScript developer. Since you can define variables on the fly with different data types, this sure seems like taking steps backwards.

It turns out this can be huge for performance. Checking data types at compile time means not having to check them at runtime. It also prevents errors before they happen. In JavaScript, you will get a runtime exception if a function expects a number but receives an object. In Java, your code will fail before you can even run it!

Functions

Since JavaScript is dynamically typed, we don't have to worry about type definitions when writing functions. With Java, we do.

JavaScript function

var getName = function(name){
  console.log(name);
}

Java function

public void printName(String name){
 System.out.println(name)
}

In the first example we define a function that takes a single parameter name and set it equal to a getName variable. Notice how we didn't define a return type or specify the data types for our arguments.

With Java we have to explicitly define a return type. This is the data type we expect the function to return. In this case, we simply use void since our function doesn't return anything.

If we were to return a string, it would look something like this

public String returnName(String name){
  return name;
}

Access modifiers

In the above examples, our Java functions start with the public prefix. This is known as an access modifier. Access modifiers set the accessibility for a particular function or variable relative to a given class. Access modifiers are not inherently supported in JavaScript. When you define a method as public then foreign objects and other classes can call Person.returnName('Sam'). If you were to use private then other classes would not be able to call this method.

The same concept applies to variables. It should be noted that access modifiers are optional and any function/variable defined without an access modifier defaults to public.

Classes

Classes are the cornerstone of object oriented programming. Classes allow you to separate your app logic into individual components that communicate with one another. While JavaScript has supported object-oriented inheritance models for years, the ES6 standard is making it easier than ever to work with classes in JavaScript. Here is an example of a JavaScript class (using ES6) and it's equivalent in Java.

Person.js

class Person{
  constructor(age, name){
    this.age = age;
    this.name = name;
  }
}

Person.java

public class Person {
  int age;
  String name;

  public Person(int age, String firstName ){
    age = age;
    name = firstName;
  }

  public static void main(String[] args) {
    Person person = new Person(25, "Sam");
    System.out.println(person.name);
  }
}

Objects (Dictionaries and Hash Maps)

Dictionaries are data structures that use key-value pairs to quickly store and retrieve data.

JavaScript Dictionary

var dict = {a:2, b:6, c:5}
// returns 2
dict.a

Java Hash Map

//import all java.util classes
import java.util.*;
Map map = new HashMap();
map.put("a", "2");

//returns 2
map.get("a");

In our JavaScript example, we can easily define a dictionary like object on the fly. Notice how the object doesn't require specific data types and we can set virtually anything to a key/value.

The Java implementation is a bit more complex. Java has a dedicated library (java.utils) for collections, event models, and date/time facilities. While the java.utils library has several classes for defining dictionaries, the HashMap class is more commonly used. Notice how we define the ke/value data types via <String, String>.

Arrays

Similar to dictionaries, Java uses the java.util library for working with arrays. While JavaScript arrays are inherently mutable, Java's Array class only supports pre-defined, fixed-length arrays. To achieve mutable arrays in Java, the ArrayList subclass is used.

JavaScript array

var arr = [1,2,3,4]

Java array

//import ArrayList from java.utils
import java.util.ArrayList;
ArrayList names = new ArrayList();
names.add("Sam");

Notice how our Java example defines a mutable array via the ArrayList class (imported from the java.utils library). The ArrayList takes a specific data type meaning only strings can be added to this array.

Loops

The JavaScript syntax for basic iterations (such as a for loop) is similar to Java.

JavaScript for loop

for(var i=0; i<5; i++){
  console.log(i);
}
for(int i=0; i<5; i++){
  System.out.println(i);
}

Both implementations are very similar. The Java example only requires the additional type definition for the incremented int i.

Conclusion

While JavaScript and Java are fundamentally different, they share many of the same design principles. Both are object oriented in nature and use classes to define objects and their relationships with one another. Both use similar data types for similar things (arrays are for ordered lists, dictionaries are for fast lookups, etc).

JavaScript is evolving to be more Java like. Runtime environments like Google's V8 engine are using inline-caching and just-in-time compilers to change how JavaScript runs in the browser. Even libraries like TypeScript.js are bringing static type checking to JavaScript development environments. It may be painful at first but learning Java will help you grow as a developer and also prepare you for the future of JavaScript development.

Your thoughts?