Java Introduction

Java Introduction Notes

Lesson Overview

  • By the end of this lesson, you should be able to:
    • Discuss key differences between Java and Python.
    • Install the Java Development Kit and a Java IDE on your computer.
    • Use JShell to run Java REPL sessions.
    • Use a Java IDE to create, compile, and run a simple Java program.

What You Already Know

  • Computers perform very simple instructions very quickly.
    • See: https://www.youtube.com/watch?v=Z5JC9Ve1sfI
  • A computer program is a sequence of instructions.
  • Programming languages are formal languages understood by both humans and computers.
  • Teams of people must be able to express complex computations and understand/update code.
  • Interpreters/compilers convert code files into machine language.
  • Most programming languages are 'equivalent' in that they can perform:
    1. Data retrieval (Input).
    2. Data storage (Output).
    3. Arithmetic operations (Increment/Multiply/etc).
    4. Conditional execution (If/else).
    5. Repetition (loops, recursive functions).
  • Some languages are more effective at expressing certain computations.

Programming Languages Task Applicability

  • Desktop apps: C#, Java
  • Web apps: C#, Elixir, Go, Java, JavaScript, PHP, Python
  • Scripting: Bash, Lua, Python
  • Database programming: SQL
  • Concurrent systems: Elixir, Erlang, Go
  • Embedded & OS: Assembly, C, C++, Rust
  • Scientific computing: Python, R, Julia
  • Games: C++, C#, Java, Lua
  • Mobile Apps: Java, Kotlin, Swift
  • Mind expansion: Haskell, LISP, Racket, esolangs

Language Types: Interpreted

  • Code files are executed directly by an interpreter.
  • The interpreter converts code into machine code at run time.
  • Execution is limited to platforms on which the interpreter can run.
  • Examples: JavaScript, PHP, Python, Ruby.

Language Types: Compiled

  • A compiler converts code files into executable files for the target platform.
  • Executable files are executed directly.
  • Examples: C, C++, Rust, Swift.

Language Types: Hybrid

  • A compiler converts code files into an intermediate bytecode.
  • The bytecode is executed by a virtual machine (a bytecode interpreter).
  • Can be executed on any platform supported by the virtual machine.
  • Examples: C#, Java, Erlang.

Compiled vs Interpreted vs Hybrid

  • An advanced interpreter has many features of a compiler.
  • There's a historical perspective:
    • Initially, the difference between an interpreter and a compiler is unclear.
    • After experience, the distinction becomes obvious.
    • With more experience, the lines blur again.

Java

  • Java is a hybrid language.
  • The compiler converts Java code files into Java bytecode.
  • The Java Virtual Machine (JVM) runs Java bytecode files.
  • JVM is supported on many hardware platforms.

Java vs JavaScript

  • Java and JavaScript are distinct languages.
  • Similar names are due to 1990s marketing.
  • Be careful when searching for information about either language!

Java Development Kit (JDK)

  • To run Java programs, the JVM must be installed.
  • To create Java programs, the JDK is needed.
  • The JDK includes:
    • JVM (java).
    • Compiler (javac).
    • REPL shell (jshell).
  • Multiple JDKs can be installed on one device.
  • Ensure the correct JDK is used when creating a Java program.

JDK Implementations and Versions

  • The Java language has a programming language specification.
  • Oracle owns the specification.
  • Vendors produce JDK implementations:
    • Amazon (Corretto).
    • Microsoft (Microsoft Build of OpenJDK).
    • Oracle (Oracle JDK, OpenJDK).
  • Implementations vary in licensing and performance.
  • The Java language specification is updated regularly.
  • Long-Term Support (LTS) versions receive regular security updates and patches.
  • Using an LTS version is recommended for production development.
    • Version 1.0: 1996, First release of Java
    • Version 5: 2004, Generic classes, annotations
    • Version 8 (LTS): 2014, Lambda expressions, streams
    • Version 11 (LTS): 2018, Java FX, Java EE removed from JDK
    • Version 21 (LTS): 2023, Most recent LTS

Java REPL

  • As of Java 9, the JDK comes with a REPL shell named jshell.
  • Example usage:
$ jshell
// | Welcome to JShell -- Version 17.0.1
// | For an introduction type: /help intro
jshell> int x = 1;
x ==> 1
jshell> int y = 2;
y ==> 2
jshell> x + y
$3 ==> 3
jshell> /exit

Java Syntax

  • A programming language's syntax is its 'grammatical rules'.
  • Syntax errors occur when you break those rules.
  • In a compiled language, syntax errors are detected by the compiler and are sometimes called compile-time errors.
  • Java is case-sensitive.
  • The Java compiler will consider these three different tokens:
    • foo
    • Foo
    • FOO
  • Instructions end in semi-colons.
  • Code blocks are wrapped in curly braces.
  • Indentation is NOT part of syntax (unlike Python).
  • Use newlines and indentation to make your code more readable!

Java Syntax - Comments

  • One-line comments:
// This is a one-line comment
int x = 1; // Everything until the end of the line is a comment
  • Multi-line comments:
/* This is a multi-line comment.
   It can span multiple lines.
   Everything inside the opening slash-star and the closing star-slash is a comment */

Values and Variables

  • A value is data that can be represented by a program.
  • Usually stored in computer memory.
  • Variables are labels for the locations where values are stored.
  • Example:
Memory Address | Value
--------------|------
0x1001        | 42

Static vs Dynamic Typing

  • Python is dynamically typed; variable type is determined at run-time.
  • Java is statically typed; variable type must be declared in code and is verified at compile time.
  • Example:
int x = 42;  // OK!

Static Typing in Java

  • Values assigned to variables must correspond to their declared types.
int x = 1;  // OK
String greet = "Hi";  // OK
boolean isHappy = true; // OK
int x = "12";  // Error!
String s = 12; // Error!

Declaration and Assignment

  • In Java, variable declaration and assignment can be separate.
// Declarations:
int x;
String s;
boolean b;

// Assignment:
x = 1;
s = "abc";
b = true;
  • Variable type is only necessary on declaration.

Common Mistakes in Variable Assignment

int x;
String s;
boolean b;
x = s;  // Error! Type mismatch
y = 2;  // Error! Undeclared variable
boolean c = b;  // Error! Variable b has no value

Variable Assignment

  • Assignment is a statement, not a mathematical equality.
int x = 1;
int y = x;  // y has value 1
x = 2;  // y STILL has value 1
y = x;  // y NOW has value 2

Type Inference

  • The var keyword can be used in place of a variable's type if it is initialized upon declaration.
var x = 42;  // x is an int
var s = "abc"; // s is a String
var y;  // Error! Cannot use 'var' without initialization
  • Useful for complex types:
var L = new ArrayList<HashMap<String,String>>();

Variable Names

  • May include:
    • Alphabetical symbols.
    • Numbers (but not as the first character).
    • Underscore (_).
  • Keywords may NOT be used as variable names.
  • Convention: camelCasing (lower-case first letter, upper-case for subsequent words).
int typicalVariableNameInJava = 1;

Types in Java

  • Every value has a type.
  • Two categories of types:
    • Primitive types.
    • Object types.

Primitive Types

  • Pure values with no methods.
PrimitiveDescription
boolean1 bit – either true or false
byte8-bit integer
short16-bit integer
int32-bit integer
long64-bit integer
float32-bit floating point number
double64-bit floating point number
char16-bit Unicode character
  • Primitive type names start with a lowercase letter.

Object Types

  • Anything that is not one of the 8 primitive types is an object type.
  • Variables store a reference to the location where the actual data is stored
  • Object types may be composite.
  • Names start with an uppercase letter (by convention).
String s; // Java Strings are objects
Object o; // The 'supertype' of all object types in Java
ArrayList list; // Much like Python's list

Object Types - References

  • Object type variables are references.
String s = "Hi!";
String t = s;  // Aliasing assignment!

Arrays

  • Ordered collection of values.
  • Similar to Python's lists, but more limited.
FeaturePython listJava Array
Element TypesMay be of different typesAll elements must be of the same type
Methods/PropertiesMany built-in methods and propertiesOnly one built-in property: length
ResizableCan be resizedFixed length
Literal[1, 2, 3]{1, 2, 3}
Type DeclarationNo type declarationint[]
IndexingmyArray[0]myArray[0]
Reference/Object TypesIs a reference typeIs a reference (object) type

Array Declaration

  • Example:
int[] myArray = { 1, 2, 3 };
  • int[]: Type declaration specifying an ARRAY of ints.
  • { 1, 2, 3 }: Array literal using curly braces.
  • myArray.length evaluates to 3.

Creating Java Programs

  • Any text editor can be used to write Java programs.
  • The javac command compiles .java files into Java bytecode (.class files).
  • The java command runs Java bytecode.
$ ls MyApp.java
$ javac MyApp.java
$ ls MyApp.class MyApp.java
$ java MyApp

IDEs for Java

  • Most Java coders use an Integrated Development Environment (IDE).
  • Examples:
    • IntelliJ IDEA
    • Eclipse
    • Netbeans
    • Visual Studio Code

Classes

  • Object types are defined using classes.
  • The JDK has many pre-defined classes.
  • You can define your own classes (custom object types).
  • In Java, EVERY code file must be a class.
  • The file name MUST be the same as the class name.
public class MyApp { }
  • class keyword defines a class.
  • public keyword indicates the 'visibility' of this class
  • All code belonging to the class must go in its body (inside the curly braces).

Function Definition Statements

  • A function (a.k.a procedure, or subroutine) consisting of a set of instructions may be created using a function definition statement
  • Functions may be called/applied to execute the set of instructions
  • Functions may return a value
  • Arguments may be used to provide input values to a function
  • Arguments are assigned to local variables called parameters in the function's instruction set

Functions

  • In Java, functions must belong to a class.
  • Two kinds of functions:
    • Class methods
      • Associated with the class
      • Call from class name, as in Math.sqrt(25)
    • Instance methods
      • Associated with an instance of the class (an object)
      • Call from object reference, as in file.write("something")

Class Methods

  • For now, only class methods will be written (though instance methods may be called).
  • Class methods are as close as you can get in Java to Python-style top-level functions

Function Definitions in Java

  • Must specify:
    • Visibility.
    • Binding.
    • Return type.
    • Name.
    • Type and name of each parameter.

Function Example

public class MyApp {
 public static void greet(String name) {
  System.out.println("Hello, " + name);
 }
}
  • Visibility: public (can be called from outside the class), or private (only from inside the class).
  • Binding: static (class method), or non-static (instance method).
  • Return Type: Specify the type of the value returned from the function or void if no value is returned.
  • Function Name: Same naming rules as variables, convention is to start with a lowercase letter
  • Parameter List: Each parameter requires a type and a name, separated by commas.
  • System.out.println(): Java's equivalent to Python's print function.

Program Execution

  • Python: Execution begins at the first instruction of the executed code file.
  • Java: Execution begins at the first instruction of the main class method in the executed bytecode file.
public class MyApp {
 public static void greet(String name) {
  System.out.println("Hello, " + name);
 }

 public static void main(String[] args) {
  greet("world");
 }
}
  • The main method receives command line arguments as an array of String objects (similar to Python's sys.argv).
  • Could also write MyApp.greet("world") but since we are in the MyApp class already it is not necessary.

Static Typing Revisited

  • Yes, Java programs are typically more verbose than equivalent Python programs. This is partly because Java is statically typed…
  • Writing statically typed programs that run can feel more challenging than writing programs in a dynamically typed language.
    • More code necessary to declare types
    • Program won't compile unless all assigned values match type declarations
  • BUT! Never need to write code like this:
def triple(n):
 assert isinstance(n, (int, float)), "n must be a number!"
 return n*3

print(triple("this shouldn't work"))
  • Statically typed languages force you to fix type errors
  • More initial work to get program to run, more verbose code
  • Less likely to encounter type errors during run-time
  • Better code navigation and automated refactoring tools in IDEs
  • Usually better for large software projects and/or teams
  • Dynamically typed languages allow you to 'ignore' types
  • Quick prototyping, usually more concise code
  • BUT type errors can cause run-time errors
  • Less powerful code navigation and automated refactoring tools in IDEs
  • More appropriate for prototyping and smaller software projects

Static Typing Benefits

  • Static typing allows the compiler to catch an entire category of bugs before you even run the program!
public class MyApp {
 public static int triple(int n) {
  return n * 3;
 }

 public static void main(String[] args) {
  System.out.println(triple("This won't compile!"));
 }
}
  • The compiler checks all calls of triple and verifies that arguments are correct type

Static vs. Dynamic

  • static == compile-time; dynamic == run-time
  • Terms that involve the term static refer to aspects of a program that are determined at compile-time
  • Static typing – types of variables/parameters must be declared and correct at compile-time
  • In contrast, terms that involve the term dynamic usually refer to aspects of a program that are determined at run-time
  • Dynamic typing – types of variables/parameters not determined until run-time

Static Typing Revisited

  • Working in a dynamically typed language can feel more productive initially, but this is often a false sense of security
  • All the type errors that a statically typed language forces you to deal with are lurking as potential bugs in your dynamically typed code

Errors

  • Compile-time errors
    • Errors caught during compilation
    • I.e., your code involves an instruction that cannot be compiled/interpreted
    • Syntax and Type errors are compile-time errors
  • Run-time errors
    • Errors that occur while the program is running
    • I.e., your code involves an instruction that is impossible at run-time
  • Semantic / logic errors
    • Errors in program logic / behaviour
    • I.e., your code is logically incorrect
Compile-time Errors
  • Occur when attempting to compile the program
  • Often indicated by IDE even before compilation
  • Prevent code from being compiled (and hence from being executed)
  • Examples.
    • Syntax errors
    • Type errors
      • Only in a statically typed language
      • In a dynamically typed language, type errors are run-time errors
Run-time Errors
  • Occur while program is running
  • Cause program to end (unless the error is explicitly handled)
  • Examples
    • Division by 0
    • I/O errors (file not found, invalid permission, etc.)
Semantic Errors
  • Cause unexpected / incorrect program behavior
  • Usually do NOT cause program to crash
  • Caused by incorrect logic in program