Skip to main content

Ch 1.3 Java Basic Structure and Syntax

Let's now learn how to write and execute Java code in practice. This chapter covers the anatomy of a Java file, the meaning of each keyword in the main method, comments, naming conventions, output methods, user input, and a complete calculator program.


1. Anatomy of a Java Source File

A Java source file (.java) follows a defined structure. Let's examine each part through an example.

// 1. Package declaration (optional, must be at the very top)
package com.example.myapp;

// 2. Import declarations (bring in external classes)
import java.util.Scanner;
import java.util.ArrayList;

// 3. Class declaration (must match the filename)
public class MyFirstProgram {

// 4. Field (instance variable) declarations
private String programName = "My First Program";

// 5. Static field (class variable) declarations
private static int runCount = 0;

// 6. main method — program entry point
public static void main(String[] args) {

// 7. Local variable declaration and use
String message = "Hello, Java!";
System.out.println(message);

runCount++;
System.out.println("Run count: " + runCount);
}
}

Component Summary

ComponentLocationRequiredDescription
package declarationVery topOptionalDefines the class namespace
import declarationsAfter packageOptionalDeclares use of external classes
Class declarationFile bodyRequiredAll code must live inside a class
main methodInside classRequired (to run)The entry point the JVM looks for

2. Breaking Down public static void main(String[] args)

This declaration is the most important structure in Java. Let's understand each keyword one by one.

public   static   void   main(String[] args)
1 2 3 4 5

1. public (access modifier)

  • Means this method can be called from anywhere
  • The JVM calls main from outside the program, so it must be public

2. static (static method)

  • Means this method can be called directly on the class without creating an object
  • The JVM calls main without instantiating any object, so it must be static

3. void (return type)

  • Means this method returns nothing
  • Program exit codes are handled separately via System.exit(0)

4. main (method name)

  • The fixed name the JVM recognizes as the entry point
  • Changing the case (Main, MAIN) causes the JVM to not recognize it

5. String[] args (parameter)

  • Receives command-line arguments passed when the program is launched as a String array
  • args is a conventional name, short for arguments
public class CommandLineArgs {
public static void main(String[] args) {
System.out.println("Number of arguments: " + args.length);

for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "] = " + args[i]);
}
}
}

Example Execution:

java CommandLineArgs Hello World 123
# Number of arguments: 3
# args[0] = Hello
# args[1] = World
# args[2] = 123
note

Starting from Java 21, a simplified main method (Preview feature) allows writing just the main method without a class declaration in single-file programs. However, mastering the standard form first is essential.


3. Comments

Comments are used to leave explanations in code. The compiler ignores them completely.

3.1 Single-Line Comment (//)

public class CommentExample {
public static void main(String[] args) {
// This is a single-line comment
int age = 25; // Can also be placed at the end of a line

// System.out.println("This line will not execute");

System.out.println("Age: " + age);
}
}

3.2 Multi-Line Comment (/* */)

public class MultiLineComment {
public static void main(String[] args) {
/*
* This is a multi-line comment.
* Often used to temporarily disable blocks of code.
* The * at the start of each line is conventional, not required.
*/
int x = 10;
int y = 20;

/* int z = x + y; -- temporarily disabled */

System.out.println(x + y);
}
}

3.3 JavaDoc Comment (/** */)

Used to auto-generate API documentation. The javadoc tool reads these comments to produce HTML docs.

/**
* A class for calculating rectangle areas.
*
* @author John Doe
* @version 1.0
* @since 2024-01-01
*/
public class Rectangle {

/**
* Calculates the area of a rectangle given width and height.
*
* @param width the width of the rectangle (must be positive)
* @param height the height of the rectangle (must be positive)
* @return the calculated area (width x height)
* @throws IllegalArgumentException if width or height is zero or negative
*/
public static double calculateArea(double width, double height) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Width and height must be positive.");
}
return width * height;
}

public static void main(String[] args) {
double area = calculateArea(5.0, 3.0);
System.out.println("Area: " + area); // 15.0
}
}

Key JavaDoc Tags:

TagDescriptionExample
@paramParameter description@param name the user's name
@returnReturn value description@return the calculated result
@throwsPossible exceptions@throws NullPointerException
@authorAuthor name@author John Doe
@versionVersion@version 2.1
@sinceVersion when added@since Java 8
@seeSee also@see String#length()
@deprecatedMarks as deprecated@deprecated will be removed next version

4. Naming Conventions

Java follows industry-standard naming conventions. Following these makes code readable for other developers.

4.1 camelCase — Variables and Methods

First word lowercase, subsequent words start with uppercase.

// Variable names (camelCase)
int studentAge = 20;
String firstName = "John";
boolean isLoggedIn = false;
double monthlyIncome = 3500000.0;

// Method names (camelCase)
public void printStudentInfo() { }
public int calculateTotalScore() { return 0; }
public boolean isValidEmail(String email) { return true; }

4.2 PascalCase — Classes, Interfaces, and Enums

Every word starts with uppercase (also called UpperCamelCase).

// Class names (PascalCase)
public class StudentManager { }
public class HttpRequestHandler { }

// Interface names (PascalCase)
public interface Printable { }
public interface DataProcessor { }

// Enum names (PascalCase)
public enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY }

4.3 UPPER_SNAKE_CASE — Constants

All uppercase letters, words separated by underscores.

// Constants (static final fields)
public static final double PI = 3.141592653589793;
public static final int MAX_RETRY_COUNT = 3;
public static final String DEFAULT_CHARSET = "UTF-8";
public static final int HTTP_OK = 200;

4.4 Package Names — Lowercase Only

package com.mycompany.project.util;   // all lowercase
package kr.co.example.service; // reverse domain order

Comprehensive Naming Example:

package com.example.school;  // package: lowercase

public class StudentGradeManager { // class: PascalCase

private static final int MAX_SCORE = 100; // constant: UPPER_SNAKE_CASE
private static final String PASS_GRADE = "Pass";

private String studentName; // variable: camelCase
private int examScore;
private boolean hasPassed;

public StudentGradeManager(String studentName, int examScore) {
this.studentName = studentName;
this.examScore = examScore;
this.hasPassed = examScore >= 60;
}

public void printGradeReport() { // method: camelCase
String result = hasPassed ? PASS_GRADE : "Fail";
System.out.printf("%s: %d points (%s)%n", studentName, examScore, result);
}

public static void main(String[] args) {
StudentGradeManager student = new StudentGradeManager("John", 85);
student.printGradeReport(); // John: 85 points (Pass)
}
}
warning

Ignoring Java naming conventions won't cause compilation errors, but it will draw criticism in code reviews and trigger warnings from code quality tools like Checkstyle and SonarQube. Build good habits from the start.


5. Java Coding Conventions

5.1 Indentation

Use 4 spaces (not tabs) for indentation.

public class IndentExample {
public static void main(String[] args) {
if (true) { // 4-space indent
System.out.println("if");
if (true) {
System.out.println("nested if"); // 8-space indent
}
}
}
}

5.2 Brace Placement

Opening brace { on the same line, closing brace } on a new line (K&R style).

// Recommended style (K&R)
public void goodStyle() {
if (condition) {
doSomething();
} else {
doOther();
}
}

// Discouraged style in Java (Allman style)
public void differentStyle()
{
if (condition)
{
doSomething();
}
}

5.3 Spacing

// Spaces on both sides of operators
int result = a + b; // good
int result = a+b; // avoid

// Space after commas
method(arg1, arg2, arg3); // good
method(arg1,arg2,arg3); // avoid

// No space between method name and parenthesis
void myMethod() { } // good
void myMethod () { } // avoid

6. Output Methods — Complete Reference

6.1 Comparing Three Output Methods

public class PrintComparison {
public static void main(String[] args) {

// 1. System.out.println: prints and then adds a newline
System.out.println("Line 1");
System.out.println("Line 2");
// Output:
// Line 1
// Line 2

// 2. System.out.print: prints without a newline
System.out.print("A");
System.out.print("B");
System.out.print("C");
System.out.println(); // manual newline
// Output: ABC

// 3. System.out.printf: formatted output (no newline by default)
System.out.printf("Name: %s, Age: %d%n", "John", 25);
// Output: Name: John, Age: 25
}
}

6.2 printf Format Specifiers

printf is based on C-style formatted output.

SpecifierTypeDescriptionExample
%dIntegerDecimal integerprintf("%d", 42)42
%fFloatFloating-point numberprintf("%f", 3.14)3.140000
%.2fFloat2 decimal placesprintf("%.2f", 3.14159)3.14
%sStringString valueprintf("%s", "Java")Java
%cCharSingle characterprintf("%c", 'A')A
%bBooleantrue/falseprintf("%b", true)true
%nNewlineOS-independent newlineprintf("Hi%n")Hi\n
%10dIntegerRight-aligned in 10 charsprintf("%10d", 42) 42
%-10dIntegerLeft-aligned in 10 charsprintf("%-10d", 42)42
%05dIntegerZero-padded to 5 digitsprintf("%05d", 42)00042
public class PrintfExample {
public static void main(String[] args) {
String name = "Alice";
int age = 28;
double height = 165.5;
double score = 95.678;

// Basic formatting
System.out.printf("Name: %s%n", name);
System.out.printf("Age: %d%n", age);
System.out.printf("Height: %.1fcm%n", height);

// Decimal place control
System.out.printf("Score: %.2f%n", score); // 95.68

// Alignment and padding
System.out.printf("|%10s|%-10s|%n", "right", "left");
System.out.printf("|%10d|%-10d|%n", 42, 42);
System.out.printf("|%010d|%n", 42); // |0000000042|

// Grade report example
System.out.println("=== Grade Report ===");
System.out.printf("%-8s %5s %5s%n", "Name", "Score", "Grade");
System.out.printf("%-8s %5d %5s%n", "Alice", 95, "A");
System.out.printf("%-8s %5d %5s%n", "Bob", 82, "B");
System.out.printf("%-8s %5d %5s%n", "Charlie", 71, "C");
}
}

Output:

Name: Alice
Age: 28
Height: 165.5cm
Score: 95.68
| right|left |
| 42|42 |
|0000000042|
=== Grade Report ===
Name Score Grade
Alice 95 A
Bob 82 B
Charlie 71 C

7. Reading User Input with Scanner

The Scanner class allows you to read input from the console.

import java.util.Scanner;

public class ScannerExample {
public static void main(String[] args) {
// Create a Scanner object (System.in = standard input stream)
Scanner scanner = new Scanner(System.in);

System.out.print("Enter your name: ");
String name = scanner.nextLine(); // read full line

System.out.print("Enter your age: ");
int age = scanner.nextInt(); // read integer

System.out.print("Enter your height (cm): ");
double height = scanner.nextDouble(); // read decimal

System.out.printf("Hello, %s! Age %d, height %.1fcm.%n",
name, age, height);

// Close the Scanner to release the resource
scanner.close();
}
}

Key Scanner Methods:

MethodReturn TypeDescription
next()StringReads one token (up to whitespace)
nextLine()StringReads the entire line up to newline
nextInt()intReads an integer
nextDouble()doubleReads a decimal number
nextBoolean()booleanReads true/false
nextLong()longReads a large integer
hasNext()booleanChecks if more tokens are available
warning

Calling nextLine() immediately after nextInt() or nextDouble() reads an empty string. This is because the newline character left in the buffer after numeric input is consumed by nextLine().

int age = scanner.nextInt();
scanner.nextLine(); // consume the leftover newline
String name = scanner.nextLine(); // now reads correctly

8. Variable Declaration and Initialization

Java is a strongly typed language— every variable must declare its type before use.

public class VariableExample {
public static void main(String[] args) {
// Declare and initialize together
int count = 0;
String greeting = "Hello";
double pi = 3.14159;
boolean isActive = true;

// Declare first, initialize later
int result;
result = 100; // must be initialized before use

// Multiple variables in one line (same type only — not recommended)
int x = 1, y = 2, z = 3;

// Java 10+ var keyword (type inference)
var message = "Available since Java 10"; // inferred as String
var number = 42; // inferred as int

System.out.println(count + " " + greeting);
System.out.println("pi = " + pi);
System.out.println("result = " + result);
}
}

Primitive Data Types

TypeSizeDefaultRangeExample
byte1 byte0-128 to 127byte b = 100;
short2 bytes0-32768 to 32767short s = 1000;
int4 bytes0approx. +/-2.1 billionint i = 100000;
long8 bytes0Lapprox. +/-9.2 quintillionlong l = 100L;
float4 bytes0.0f~7 decimal digitsfloat f = 3.14f;
double8 bytes0.0~15 decimal digitsdouble d = 3.14;
char2 bytes'\u0000'0 to 65535 (Unicode)char c = 'A';
boolean1 bitfalsetrue or falseboolean b = true;

9. Expressions and Statements

Expressions

A piece of code that evaluates to a value.

// Arithmetic expressions
3 + 4 // value: 7
x * y // value: product of x and y
a > b // value: true or false

// Method call expressions
Math.max(10, 20) // value: 20
"Hello".length() // value: 5

// Assignment expressions
x = 5 // value: 5 (the value of x after assignment)

Statements

The smallest executable unit of code, terminated by a semicolon (;).

public class StatementExample {
public static void main(String[] args) {
// Declaration statement
int x = 10;

// Expression statements
x = 20; // assignment
x++; // increment
System.out.println(x); // method call

// Control statements (contain blocks, no trailing semicolon)
if (x > 15) {
System.out.println("Greater than 15");
}

// Block statement (groups multiple statements in braces)
{
int temp = 100;
System.out.println("Inside block: " + temp);
}
// temp is not accessible here (block scope)
}
}

10. Three Types of Errors

Java errors are classified into three categories based on when they occur.

10.1 Compile-Time Error

Occurs during the compilation phase when source code is converted to bytecode. The IDE or javac reports these immediately — the easiest errors to catch.

public class CompileErrorExample {
public static void main(String[] args) {
// Compile error examples:

int x = "Hello"; // Type mismatch
// → error: incompatible types: String cannot be converted to int

System.out.println(y); // Using an undeclared variable
// → error: cannot find symbol

if (true) // Missing semicolon (error on next line)
System.out.println("OK")
// → error: ';' expected
}
}

10.2 Runtime Error

Occurs while the program is executing. The code compiles successfully but throws an exception during execution.

public class RuntimeErrorExample {
public static void main(String[] args) {
// 1. NullPointerException: calling method/field on null reference
String s = null;
System.out.println(s.length()); // NullPointerException!

// 2. ArrayIndexOutOfBoundsException: accessing index out of range
int[] arr = new int[3]; // valid indices: 0, 1, 2
arr[5] = 10; // ArrayIndexOutOfBoundsException!

// 3. NumberFormatException: parsing an invalid number string
int n = Integer.parseInt("abc"); // NumberFormatException!

// 4. ArithmeticException: division by zero
int result = 10 / 0; // ArithmeticException!
}
}

10.3 Logic Error

The code compiles and runs without errors, but the output is not what was intended. The hardest type to find.

public class LogicErrorExample {
public static void main(String[] args) {
// Formula: Fahrenheit = Celsius * 9/5 + 32
double celsius = 100.0;

// Logic error: integer division makes 9/5 = 1, not 1.8
double fahrenheit = celsius * 9/5 + 32; // wrong: 132.0
// Correct: celsius * 9.0/5 + 32 → 212.0

System.out.println(celsius + "C = " + fahrenheit + "F");
// Output: 100.0C = 132.0F (wrong! correct answer is 212.0F)
}
}

Error Type Summary:

TypeWhen It OccursEase of DetectionExamples
Compile ErrorDuring javacVery easy (IDE highlights immediately)Syntax errors, type mismatches
Runtime ErrorDuring executionModerate (stack trace provided)NullPointerException
Logic ErrorAfter reviewing resultsDifficult (requires debugger)Incorrect algorithm

11. Hands-On Project: Arithmetic Calculator

A complete calculator program that brings together everything covered in this chapter.

import java.util.Scanner;

/**
* Arithmetic Calculator
* Accepts two numbers and an operator from the user and prints the result.
*/
public class Calculator {

/**
* Returns the sum of two numbers.
*/
public static double add(double a, double b) {
return a + b;
}

/**
* Returns the difference of two numbers.
*/
public static double subtract(double a, double b) {
return a - b;
}

/**
* Returns the product of two numbers.
*/
public static double multiply(double a, double b) {
return a * b;
}

/**
* Returns the quotient of two numbers.
*
* @throws ArithmeticException if dividing by zero
*/
public static double divide(double a, double b) {
if (b == 0) {
throw new ArithmeticException("Cannot divide by zero!");
}
return a / b;
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

System.out.println("===== Arithmetic Calculator =====");
System.out.println("Operators: + (add), - (subtract), * (multiply), / (divide)");
System.out.println();

// Read first number
System.out.print("Enter the first number: ");
double num1 = scanner.nextDouble();

// Read operator
System.out.print("Enter the operator (+, -, *, /): ");
String operator = scanner.next();

// Read second number
System.out.print("Enter the second number: ");
double num2 = scanner.nextDouble();

// Perform calculation
double result;
boolean isValid = true;

switch (operator) {
case "+":
result = add(num1, num2);
break;
case "-":
result = subtract(num1, num2);
break;
case "*":
result = multiply(num1, num2);
break;
case "/":
if (num2 == 0) {
System.out.println("Error: Cannot divide by zero!");
isValid = false;
result = 0;
} else {
result = divide(num1, num2);
}
break;
default:
System.out.println("Error: Invalid operator '" + operator + "'");
isValid = false;
result = 0;
}

// Print result
if (isValid) {
System.out.println();
System.out.println("===== Result =====");

// Print without decimal if result is a whole number
if (result == (long) result) {
System.out.printf("%.0f %s %.0f = %.0f%n",
num1, operator, num2, result);
} else {
System.out.printf("%.2f %s %.2f = %.4f%n",
num1, operator, num2, result);
}
}

scanner.close();
}
}

Sample Run 1 (Addition):

===== Arithmetic Calculator =====
Operators: + (add), - (subtract), * (multiply), / (divide)

Enter the first number: 15
Enter the operator (+, -, *, /): +
Enter the second number: 27

===== Result =====
15 + 27 = 42

Sample Run 2 (Division):

Enter the first number: 10
Enter the operator (+, -, *, /): /
Enter the second number: 3

===== Result =====
10.00 / 3.00 = 3.3333

Sample Run 3 (Division by zero):

Enter the first number: 5
Enter the operator (+, -, *, /): /
Enter the second number: 0
Error: Cannot divide by zero!
tip

IntelliJ IDEA shortcut tips:

  • psvm + Tab: auto-complete public static void main(String[] args) {}
  • sout + Tab: auto-complete System.out.println()
  • souf + Tab: auto-complete System.out.printf()
  • Ctrl + Shift + F10: run the current file
  • Ctrl + /: toggle line comment on selected lines
  • Alt + Enter: show quick fix suggestions for errors

Summary

TopicKey Points
File Structurepackage → import → class → method
main Methodpublic static void main(String[] args) — JVM entry point
Comments// single-line, /* */ multi-line, /** */ JavaDoc
Naming ConventionsVariables/methods: camelCase, Classes: PascalCase, Constants: UPPER_SNAKE_CASE
Outputprintln (with newline), print (no newline), printf (formatted)
InputUse the Scanner class to read from standard input
Error TypesCompile error, Runtime error, Logic error