Java Programming Model

In this module, I listed the essential Java language features to be used in this course. I will keep updating this document as we go through the course.

Warning

This is not a comprehensive Java tutorial. For more details, please refer to the Java documentation at https://docs.oracle.com/javase/tutorial/java/index.html or other online resources.

Free Reference Books

  • Think Java: How to Think Like a Computer Scientist link

  • Think in Java link

  • The Java Tutorials link

Data Types and Expressions

  • Primitive data types

    In Java, primitive data types represent the basic building blocks of data. They are simple, predefined data types that are not derived from any other types. Examples of primitive data types include int, double, boolean, char, and others. These types hold their values directly and have a fixed size in memory.

  • Reference types

    Unlike primitive data types, reference types in Java represent objects rather than storing the actual data. They store a reference or address that points to the memory location where the object is stored. Reference types include class types, which are user-defined classes, as well as arrays and interfaces.

    • Assignment copies the reference, not the object

    • Equal comparison checks if two references point to the same object rather than comparing the values of the objects

    • Wrapper types of primitive types

      • Integer, Double, Boolean, Character, etc.

      • Automatic boxing and unboxing

  • Generics

    Generics in Java allow you to create classes, interfaces, and methods that can operate on different data types. They provide a way to define a class or method that can work with different types of data, while maintaining type safety at compile-time. Generics are useful for creating reusable code and enhancing code flexibility.

    public class Box<T> {
      private T contents;
    
      public Box(T contents) {
          this.contents = contents;
      }
    
      public T getContents() {
          return contents;
      }
    
      public void setContents(T contents) {
          this.contents = contents;
      }
    
      public static void main(String[] args) {
          Box<Integer> integerBox = new Box<>(10);
          System.out.println("Contents of integerBox: " + integerBox.getContents());
    
          Box<String> stringBox = new Box<>("Hello");
          System.out.println("Contents of stringBox: " + stringBox.getContents());
      }
    }
    

    In the above example, we have a generic class called Box which can hold any type of object. The generic type parameter T allows us to specify the type of the contents of the box when creating an instance of the class.

    Inside the Box class, we have a private field contents of type T which represents the object stored in the box. We also have getter and setter methods to access and modify the contents.

    In the main method, we create two instances of the Box class: integerBox and stringBox. We specify the type argument <Integer> for integerBox and <String> for stringBox. This ensures that the contents field of each box is of the specified type.

    Finally, we print the contents of each box using the getContents method. Since we used generics, the compiler ensures type safety, allowing us to use the getContents method without the need for explicit type casting.

  • Variables

  • Identifiers

    • Names for variables, methods, classes, etc.

    • Naming rules - start with a letter, $, or _, followed by letters, digits, $, or _

    • Naming conventions

      • Upper camel case for class names

      • Lower camel case for variable and method names

    • Case sensitivity

    • Reserved words

  • Literals

  • Expressions

    • Operators

    • Precedence

    • Associativity

    • Type conversion

Arrays

  • This is a class type stored as references in variables!

  • Declaration

  • Initialization

  • Assignment

Statements

  • Declaration

  • Assignment

  • Method call and return

  • Control flow

    • conditional

    • loop

    • break and continue

  • Shortcut notations

    • initialization

    • implicit assignment (+=, -=, *=, /=, %=)

    • single-statement block (omit braces)

    • for notations (for-each, for-in)

Object-oriented Programming in Java

Instance Variables

  • A.k.a. fields or attributes, referred as instance field in our Textbook

  • Implicit this instance variable

    • refers to the current object

    • not available in static methods

Methods

  • static vs. non-static

Static Methods

Non-Static Methods

Invocation

ClassName.methodName()

objectReference.methodName()

Method Access

Can access only other static methods within the same class

Can access both static and non-static methods within the same class

Class Dependency

No dependency on object instances

Requires an object instance of the class

Memory Allocation

Only one copy of the method exists in memory

Each object instance has its own copy of non-static methods

Use of instance variables

Cannot directly access or modify instance variables

Can directly access or modify instance variables

Overriding

Cannot be overridden

Can be overridden in subclasses

Inheritance

  • extends keyword

Interface

  • implements keyword

Other features

  • Packages

    • package keyword

    • import keyword

    • directory structure and dot in the package name