Computer Programming in Java Study Notes

Foundations of Computer Programs and Programming Languages

  • Computer Programs:

    • A program is a precise set of instructions directing a computer to perform designated tasks and produce specific results.
    • An analogy for a program is a recipe: it contains a list of variables (analogous to ingredients) and a list of statements (analogous to step-by-step directions).
    • Executing / Running: The process of executing instructions by the CPU.
    • Without software programs, computer hardware is merely an empty, non-functional machine.
    • Humans communicate intent to machines via programming languages, as computers cannot natively comprehend human natural languages.
  • Program Input and Output Process:

    • Execution requires two distinct types of input:
    1. The Program: The compiled or interpreted instruction set.
    2. The Data: The input parameters processed by the program during execution.
    • Output: The definitive calculated result or side-effect produced after executing program instructions.

  Program Input and Output Diagram

  • Nature of Programming Languages:

    • All low-level computer hardware components—including the Central Processing Unit (CPU), primary memory (RAM), and Input/Output (I/O) controllers—operate purely on machine code (binary strings consisting entirely of 0s and 1s).
    • Binary code is extremely difficult for humans to read, write, or maintain directly.
    • Programming languages serve as an essential abstraction layer between human thought processes and machine binary instructions.
    • Every programming language possesses a unique set of keywords (reserved terms recognized by the language processor) and a rigid syntax (grammar rules governing statement structure).
  • Syntax vs. Semantics:

    • Syntax: The structural grammar rules of a programming language, strictly verified by the compiler or interpreter during compilation/parsing.
    • Example (Java While Loop Syntax): while (boolean_expression) statement
    • Semantics: The logical meaning, interpretation, or runtime behavior of syntactically valid statements.
    • Semantic Error Example 1 (Array Index Out of Bounds):       int[] v = new int[10]; v[10] = 100;\text{int[] v = new int[10]; v[10] = 100;}       Here, index 1010 is syntactically correct as an integer, but semantically illegal because a 10-element array indexed from 00 only extends to index 99.
    • Semantic Error Example 2 (Uninitialized Variable Usage):       int i; i++;\text{int i; i++;}       The variable i is declared but lacks an initial value, rendering incrementation semantically invalid.
  • Hierarchy of Programming Language Levels:

    • Languages scale along a spectrum balancing execution speed against human readability and abstraction:
    1. Machine Language: Raw binary sequences (00s and 11s). Executed directly by machine hardware with maximum performance but zero abstraction.
    2. Assembly Language: Low-level instruction set utilizing mnemonic symbols (e.g., aload_0, iadd, istore_2). Highly hardware-specific (e.g., Intel 8086, Sun Sparc).
    3. High-Level Languages: Human-friendly languages abstracting memory management and machine architecture (e.g., Fortran, COBOL).
    4. Very High-Level Languages: Modern object-oriented or domain-specific high-level languages offering maximum developer productivity (e.g., Java, C++, C#).
    5. Natural Language: Human languages (e.g., English), which lack the precision required for direct computer execution.
  • Domain-Specific Language Selection:

    • Satellite Communication / Low-Level Performance: Assembly Language
    • Educational Instruction: BASIC, Pascal
    • Legacy Business Systems: COBOL
    • Web Development: JavaScript, JSP, .NET
    • Scientific Computations: Fortran, MATLAB
    • Embedded Systems & Operating Systems: C
    • Enterprise Software Systems: Java
  • Translation Mechanisms: Compilers vs. Interpreters:

    • High-level code typed by a programmer is designated as source code (contained in a source program).
    • Because processors only execute binary machine code, translators are required to convert source code to low-level instructions.
    • Compiler:
    • Processes the entire high-level source program at once, translating it completely into machine code or intermediate object code before execution.
    • Translation occurs once; the compiled executable can be executed repeatedly without re-compilation.
    • The Java Compiler (javac) translates Java source code files (.java) into intermediate, machine-independent bytecode files (.class).

  Java Compiler Diagram

  • Interpreter:
    • Reads high-level or intermediate code line-by-line, translating and executing each instruction sequentially in real time.
    • The Java Virtual Machine (JVM) utilizes an interpreter to translate bytecode instructions into hardware-specific native machine commands during execution.

  Java Interpreter Diagram

The Java Language Architecture and Development Environment

  • Historical Background of Java:

    • Authored and designed by James Gosling at Sun Microsystems in the early 1990s.
    • Gosling sought an alternative to C++ that eliminated manual memory management and complex pointer arithmetic.
    • Originally named Oak (after an oak tree outside Gosling's office).
    • Formally renamed Java in 1995 and established as a core component of Sun Microsystems' software ecosystem.
    • Designed as a consolidation language that adopted proven constructs from older languages while discarding prone-to-error mechanisms.
  • Key Features of the Java Platform:

    • Simple: Syntax derived from C++, stripped of explicit pointers, operator overloading, and manual memory freeing.
    • Platform-Independent (Portable): Governed by the paradigm "Write Once, Run Anywhere" (WORA). Compiled bytecode executes identically across disparate operating systems and processor architectures.
    • Object-Oriented: Data and behaviors are structured within encapsulated classes and objects, enhancing modularity and reusability.
    • Robust and Secure: Enforces strict type checking, robust exception handling, strict memory boundary isolation, and execution within the Virtual Machine sandbox. Incorporates automatic garbage collection to eliminate unreferenced objects and prevent memory leaks.
    • Compiled and Interpreted: Source code is compiled to intermediate bytecode (.class), which is then interpreted or JIT-compiled at runtime by the JVM.
    • Distributed: Built-in support for network protocols, allowing seamless execution across networked multi-node systems.
    • Multithreaded: Supports simultaneous execution of multiple concurrent threads within a single program context.
    • Architecture-Neutral: Execution behavior is uniform across platforms (e.g., primitive type sizes are strictly fixed regardless of system word size).
    • High-Performance: Integrates Just-In-Time (JIT) Compilers inside modern JVMs to convert heavily executed bytecode blocks directly into native machine code at runtime.
  • Target Application Domains:

    1. Standalone / Desktop Applications: Installed locally on client host machines (e.g., Acrobat Reader, Media Players, Antivirus software).
    2. Web Applications: Server-side programs generating dynamic web pages via Java Technologies like JSP, Servlets, and Spring (e.g., e-commerce engines, university student portals).
    3. Enterprise Applications: Distributed, scalable, high-security systems requiring load balancing and clustering (e.g., banking cores).
    4. Mobile Applications: Software developed for smartphones and embedded devices using Android SDK or Java ME.
  • The Five Phases of Java Program Execution:

    • Phase 1: Creation & Editing:
    • Source code is typed in a plain text editor (e.g., Notepad, TextEdit) or an Integrated Development Environment (IDE) like Eclipse, NetBeans, IntelliJ IDEA, or VS Code.
    • Saved on disk with a mandatory .java file extension.
    • Phase 2: Compilation:
    • The developer runs javac SourceFile.java.
    • The compiler checks syntax rules and translates source code into machine-independent Java Bytecode stored in a .class file on disk.
    • Phase 3: Loading into Memory:
    • Executing java SourceFile invokes the JVM.
    • The JVM Class Loader (linker) transfers .class bytecode files from persistent storage into primary RAM memory.
    • Phase 4: Bytecode Verification:
    • The Bytecode Verifier scans loaded bytecodes to confirm structural integrity, validity, and compliance with Java security restrictions, ensuring incoming network code cannot corrupt system memory.
    • Phase 5: Interpretation / Execution:
    • The JVM Interpreter reads bytecode instructions sequentially, translating them into host CPU machine commands.
    • Frequently executed code sequences are dynamically compiled to native assembly by the Just-In-Time (JIT) Compiler for near-native execution speeds.
  • Core Components Hierarchy: JVM vs. JRE vs. JDK:

    • JVM (Java Virtual Machine): The execution software engine that interprets bytecode and manages execution memory.
    • JRE (Java Runtime Environment): Includes the JVM + Standard Class Libraries Set. Provides all runtime resources required to execute existing compiled Java binaries.
    • JDK (Java Development Kit): Includes the JRE + Development Tools (the javac compiler, javadoc generator, debugger, and packaging utilities). Required by developers to compile and build Java programs.

  Core Java Environment Architecture

Problem Solving, Algorithm Design, and Flowcharting

  • Computer Programming as Problem Solving:

    • Software engineering is fundamentally a structured problem-solving discipline.
    • Complex real-world operations are recursively decomposed into simpler subtasks until reaching elementary operations executable by hardware logic gates.
    • Programmer: The author who writes code logic.
    • User: The end-user interacting with the executing system.
  • Algorithm Concept and Characteristics:

    • An algorithm is defined as a finite, ordered, unambiguous sequence of computational steps designed to resolve a specific problem.
    • The development life cycle proceeds sequentially: Analyzing Problem →\rightarrow Developing Algorithm →\rightarrow Coding →\rightarrow Testing.

  Problem Solving Life Cycle Flow

  • Standard Flowchart Graphical Notation:

  | Symbol Shape | Name | Operational Use in Flowcharting |   | :--- | :--- | :--- |   | Oval | Terminal | Denotes the explicit Start or Stop point of an algorithm program flow. |   | Parallelogram | Input / Output | Denotes data entry operations (read) or result display operations (print). |   | Rectangle | Process | Denotes computational processes, memory modifications, or mathematical operations. |   | Diamond | Decision | Denotes conditional branching points (e.g., IF/THEN/ELSE) with dual evaluation routes (True/False or Yes/No). |   | Hybrid / Arrow | Flow Line | Connects operational symbols to show the exact directional flow of program execution logic. |

  • Standard Flowchart Case Studies:
    • Example 1: Converting Length from Feet to Centimeters:
    • Formula: Lcm=Lft×30\text{Lcm} = \text{Lft} \times 30
    • Pseudocode:
      1. Input length in feet (Lft).
      2. Calculate length in centimeters (Lcm = Lft * 30).
      3. Output calculated length in centimeters (Lcm).
    • Flowchart Diagram:

      Length Conversion Flowchart Example

  • Example 2: Determining Pass/Fail Status Based on Average Marks:
    • Formula: GRADE=M1+M2+M3+M44\text{GRADE} = \frac{\text{M1} + \text{M2} + \text{M3} + \text{M4}}{4}
    • Pseudocode:
      1. Input four exam numerical marks (M1, M2, M3, M4).
      2. Compute average grade (GRADE = (M1 + M2 + M3 + M4) / 4).
      3. Evaluate IS GRADE < 50:
      • If Yes (YY): Output "FAIL".
      • If No (NN): Output "PASS".
    • Flowchart Diagram:

      Student Grade Flowchart Example

Software Development Lifecycle: Testing, Debugging, and Program Errors

  • Testing and Debugging Protocols:

    • Proactive design and accurate algorithmic mapping minimize errors before code is compiled.
    • Bug: An informal term for any flaw, error, or defect in a computer program.
    • Debugging: The systematic process of detecting, isolating, and fixing bugs.
  • Taxonomy of Software Errors:

    1. Syntax Errors:
    • Violations of the grammatical rules of the programming language.
    • Caught automatically by the compiler (javac) during compilation.
    • Prevents .class bytecode generation until resolved.
    • Examples: Omitting mandatory semicolons ;, failing to close string literal quotation marks, mismatched curly braces {}.
    1. Runtime Errors:
    • Errors occurring while the program is actively executing, forcing premature program termination (crashing).
    • The JVM halts execution and outputs an exception stack trace.
    • Examples: Attempting integer division by zero (1 / 0), referencing array elements beyond valid bounds.
    1. Logic Errors:
    • Flaws in algorithm design or formula implementation.
    • The program compiles without syntax errors and executes without runtime crashes, but outputs incorrect results.
    • Logic errors generate no warning messages, making them the most difficult errors to diagnose.
    • Example: Converting Celsius to Fahrenheit using ∙C×1.8+23{}^\bullet C \times 1.8 + 23 instead of ∙C×1.8+32{}^\bullet C \times 1.8 + 32.

Software Architecture Principles: Decomposition and Abstraction

  • System Decomposition:

    • The practice of partitioning a complex system into smaller, self-contained subproblems solved independently.
    • Decomposition Criteria:
    • Subproblems must be structured at uniform detail levels.
    • Subproblems must operate independently.
    • Subproblem solutions must recombine cleanly to resolve the macro problem.
    • Software Engineering Metrics:
    • Coupling: A metric measuring inter-module connectivity and interdependence. Minimizing coupling is ideal.
    • Cohesion: A metric measuring how logically related intra-module elements are. High cohesion is ideal.
    • Information Hiding: Designing modules to encapsulate private internal state while exposing strict interface methods.
    • Architectural Advantages: Enables parallel team development, isolates maintenance, and reduces cognitive load.
    • Limitations: Ineffective for poorly understood domain problems, indivisible atomic operations (1+11 + 1), or non-computable problems.
  • System Abstraction:

    • Filtering out irrelevant implementation specifics to expose only core operational interfaces.
    • Abstraction by Parameterization:
    • Abstracts generalized computation patterns by replacing fixed literal data with generic input parameters.
    • Implementation Example: java int squares(int x, int y) { return (x * x - y * y); } &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       Callers invoke squares(big, small) without re-writing mathematical instructions.
    • Abstraction by Specification:
    • Establishes a formal contractual boundary between client caller and implementer.
    • Exposes expected behaviors via preconditions (input requirements) and postconditions (guaranteed outputs) documented in code comments, hiding implementation specifics.

Java Program Structure, Syntax, and Code Organization

  • Anatomy of a Java Source File:
    • A complete Java source file includes up to five distinct structural layers:

  Java Program Structure Layer Layout

  1. Documentation Statements: Source comments detailing author, file purpose, and revisions.
  2. Package Statement: Defines the organizational library namespace for the class (e.g., package people;). If present, must be the very first non-comment code line.
  3. Import Statements: Explicitly imports required classes defined in external packages (e.g., import java.util.Scanner;).
  4. Class Header & Declaration: Defines the class scope and name (public class ClassName).
  5. Main Method Entry Point: The mandatory entry point where execution begins.
  • Java Documentation Comment Styles:

    • Single-Line Comments: Commences with //. Everything following // on that line is ignored by the compiler (e.g., double radius; // in cm).
    • Multi-Line Comments: Enclosed between /* and */. Spans multiple lines (e.g., /* This program runs math calculations */).
    • Javadoc Comments: Commences with /** and ends with */. Extracted by automated tools to generate HTML API documentation.
  • Java Class Naming Rules and Identifiers:

    • Identifier Rules: Must contain only alphanumeric characters (a-z, A-Z, 0-9), underscores (_), or dollar signs ($). Cannot begin with a numerical digit. Case-sensitive.
    • Class Name Convention: Naming follows UpperCamelCase (e.g., FirstProgram, CircleCalculation2).
    • Source File Matching: The public class name MUST exactly match the base file name on disk (e.g., public class FirstProgram must reside in FirstProgram.java).
  • The Main Method Signature Specification:

    • Declared explicitly as: java public static void main(String[] args) &nbsp;&nbsp;&nbsp;&nbsp;
    • Modifier Meanings:
    • public: Accessible to the external JVM environment.
    • static: Callable directly by the JVM without instantiating an object of the outer class.
    • void: Returns no value upon execution completion.
    • String[] args: Accepts an array of text string command-line arguments passed at startup.
  • Block Structure and Curly Braces Styles:

    • Groupings of execution statements are delimited by matching curly braces {} into Blocks.
    • Next-Line Style: java public class Test { public static void main(String[] args) { System.out.println("Next Line Style"); } } &nbsp;&nbsp;&nbsp;&nbsp;
    • End-Of-Line Style: java public class Test { public static void main(String[] args) { System.out.println("End of Line Style"); } } &nbsp;&nbsp;&nbsp;&nbsp;

Java Data Types, Identifiers, and Memory Management

  • Data Types Classification:
    • A Data Type dictates the set of allowed values, memory storage layout, and valid mathematical/logical operations.

  Data Types Structural Tree Diagram

  • Primitive Data Types Specifications:
    • Java defines eight fundamental primitive types:

  | Type Name | Kind of Value | Memory Allocation | Valid Numeric / Value Range |   | :--- | :--- | :--- | :--- |   | byte | Signed Integer | 1 byte (8 bits) | −128-128 to 127127 |   | short | Signed Integer | 2 bytes (16 bits) | −32,768-32,768 to 32,76732,767 |   | int | Signed Integer | 4 bytes (32 bits) | −2,147,483,648-2,147,483,648 to 2,147,483,6472,147,483,647 |   | long | Signed Integer | 8 bytes (64 bits) | −9,223,372,036,854,775,808-9,223,372,036,854,775,808 to 9,223,372,036,854,775,8079,223,372,036,854,775,807 |   | float | Single-Precision Floating-Point | 4 bytes (32 bits) | ±1.40239846×10−45\pm 1.40239846 \times 10^{-45} to ±3.40282347×1038\pm 3.40282347 \times 10^{38} |   | double | Double-Precision Floating-Point | 8 bytes (64 bits) | ±4.94065645841246544×10−324\pm 4.94065645841246544 \times 10^{-324} to ±1.79769313486231570×10308\pm 1.79769313486231570 \times 10^{308} |   | char | Unicode Character | 2 bytes (16 bits) | All Unicode symbols (numeric range 00 to 65,53565,535) |   | boolean | Logical Truth Value | 1 bit | true or false |

  • Primitive vs. Non-Primitive Data Types:

    • Primitive Types: Predefined natively by Java; names are all lowercase (int, double); variables hold raw direct literal values in memory; contain no attached methods; cannot be null.
    • Non-Primitive Types (Reference Types): Defined by developers (except standard String); names begin with uppercase letters (String, Scanner, Array); variables store memory address references pointing to heap memory objects; contain callable methods; can be assigned null.
  • Non-Primitive Focus: The String Class:

    • Strings are instances of the standard Java class java.lang.String (automatically imported).
    • Literals are enclosed within double quotation marks (e.g., `