You are on page 1of 1074

Introduction to Java Programming

By
Dr. Bharati Mishra
Computer Anatomy

• Hardware
• Operating Systems
• Software

From Wikipedia, the free encyclopedia


Hardware Anatomy

• Basic hardware components of a computer


• CPU
• Memory
• Storage
• I/O (Input/Output)
• Communication devices

Storage Communication Input Output


Memory CPU Devices
Devices Devices Devices

BUS
CPU
• CPU = Central Processing Unit
• Speed measured in MHz
• 1 MHz = 10^6 pulses per second
• Executes instructions retrieved from memory
Memory
• We are talking about RAM
• Random Access Memory
• Volatile
• Stores data
• A sequence of bytes
• Each byte = 8 bits
• Each bit can be 0 or 1

23 100 67 A P P L E X 32 Memory
(sequence of bytes )
2 @ $ 76 X 89 120 D T D

Byte
0 0 0 0 0 0 1 0 (8 bits)

Bit
Memory
• All data is encoded as 0-1
• Byte = minimum storage unit
• Large numbers are stored in more than 1 byte
Memory Address Memory Content
.
. .
. .
2000 0 1 0 0 1 0 1 0 Encoding for character ‘J’
2001 0 1 1 0 0 0 0 1 Encoding for Character ‘a’
2002 0 1 1 1 0 1 1 0 Encoding for character ‘v’
2003 0 1 1 0 0 0 0 1 Encoding for Character ‘a’
2004 0 0 0 0 0 0 1 0 Encoding for number 2
. .
. .
Memory
• Quick reminder
• Byte = minimum storage unit
• KB = 10^3 Bytes
• MB = 10^6 Bytes
• GB = 10^9 Bytes
• TB = 10^12 Bytes
• PB = 10^15 Bytes
Storage
• Memory is volatile
• Store programs & data on non-volatile devices
• Hard disks (now TB)
• CD (700 MB)
• DVD (4.7 GB)
• Blu-ray (25-100 GB)
• USB Flash drive (now 256 GB)
Output
• Monitor Display
• Quality
• Resolution
• number of pixels per square inch
• E.g. 1024 by 768
• Dot pitch
• amount of space between pixels Dot pitch
Communication
• Modem
• Uses a phone line
• Speed = 56,000 bps (bits per second)
• DSL
• Uses phone line
• 20 times faster than modem
• Cable modem
• Uses TV cable line
• Speed same as DSL
• NIC
• Used in local area networks
• E.g. 10BaseT has speed of 10 Mbps
Programming Languages Basics
Programming Languages

• Every operating system, application and mobile


app has been written in some programming
language
Popular High level Languages

•There are many programming languages


• COBOL (1959)
• FORTRAN (1957)
• BASIC (1964)
• Visual Basic (1991)
• Pascal (1970)
• Delphi (1986)
• Ada (1980)
• C (1972)
• C++ (1983)
• Objective C (1983)
• C# (2001, a Java-like language by Microsoft)
•…
Java
• We will be using Java (1991)

Duke: Java’s Mascot


Some Java Programs

• Some famous applications written in Java


• Mars exploration rover
• Hubble telescope
• Vuze
• Minecarft
• Android (mostly)
Programming Languages

• High level language (Java)


• Assembly Language
• Machine language

Difficulty of programming • High level languages

• Assembly Language

• Machine Language
Machine Language

• Machine language
• The language of CPU
• Each CPU family has its own instruction set
• Patterns of bits corresponding to different commands
• E.g. To add two numbers instruction:
• 1101101010011010
Assembly Language

• Assembly language
• Easier than machine language
• E.g. To add two numbers instruction:
• mov ax, a
add ax, b
mov c, ax
• Yet not so easy!

Assembler
Machine
Assembly Code
Language Code

0000111
mov ax, a
0000101
add ax, b
1100011
mov c, ax
0011111
1110000
High level Languages

• High level languages


• Easiest to program
• English like syntax
• E.g. To add two numbers in Java
• c = a + b;

Library Code

High Level Machine Machine


Source Code Language Code Language Code

Compiler Linker
Example Program

//This program prints Welcome to Java!


public class Welcome {
public static void main(String[] args) {
System.out.println("Welcome to Java!");
}
}

Run
Run Program
1. Compile:
• javac Welcome.java
2. Run
• java Welcome
• Caution: no .class at the end of Welcome!
Java Basics
Why Java?
•Allows you to develop and deploy applications on
• Internet for servers
• desktop computers
• small hand-held devices
Why Java?
• Applets
Java History
• Developed by James Gosling at Sun Microsystems
• First named Oak
• Later named Java 1995
• HotJava
• The first Java-enabled Web browser
• Write once, run anywhere
Some Terms
• Java = Language specification + API
• Specification: technical definition of the language
(semantic + syntax)
• API: contains predefined libraries for developing java
programs
• JVM = Java Virtual Machine
• JDK = Java Development Kit
• IDE = Integrated Development Environment
Java IDE
• Makes writing & managing large scale programs
easier
• NetBeans Open Source by Oracle
• Eclipse Open Source by IBM
• BlueJ
•…
JDK Versions
• JDK = Java Development Kit
• JDK 1.02 (1995)
• JDK 1.1 (1996)
• JDK 1.2 (1998)
• JDK 1.3 (2000)
• JDK 1.4 (2002)
• JDK 1.5 (2004) a. k. a. JDK 5 or Java 5
• JDK 1.6 (2006) a. k. a. JDK 6 or Java 6
• JDK 1.7 (2010) a. k. a. JDK 7 or Java 7
• JDK 1.8(2014) a. k. a. JDK 8 or Java 8 ….
• JDK 20 (2023)
JDK Editions
1. Java Standard Edition (Java SE)
• client-side standalone applications or applets.
2. Java Enterprise Edition (Java EE)
• server-side applications such as Java servlets and Java
Server Pages (JSP).
3. Java Micro Edition (Java ME).
• applications for mobile devices

We use Java SE.


Java is
• Simple
• Object-Oriented
• Distributed
• Robust
• Secure
• Architecture-Neutral
• Portable
• Performance
Example Program

//This program prints Welcome to Java!


public class Welcome {
public static void main(String[] args) {
System.out.println("Welcome to Java!");
}
}

Run
Programming in Java
• Object Oriented Programming ( OOP)
• main method
• Programming syntax
OOP
• Object Oriented Programming ( OOP)
• A software methodology
• Great flexibility, modularity, clarity, and reusability
• Uses “encapsulation”, “inheritance”, and
“polymorphism”
• Everything is Java is an “Object”
Object
• Real world objects
• Dog, TV set, desk, etc.
• Every object has “state” and “behavior”
• Dog object
• State: name, color, breed, hungry
• Behavior: barking, fetching, wagging tail
• In OOP
• State = “field”
• Behavior = “method”
OOP
• E.g. Dog class
• class Dog { ...description of a dog goes here... }
• Each object (class) has
• State (Properties or data fields) Dog
• Behavior (methods) - max
- 2
• Can have instances - 30
Instances
Bark()
Eat ()
Class
Dog
Name Dog
- Name
- Age - cooper
Properties - Weight - 3.5
- 34
Methods Bark()
Eat () Bark()
Eat ()
Class Example

• Here is another example of a class:


• class Window { ... }
• Here are some examples of Windows:
Class Definition
• Example:
Data usually goes first in a class
class Dog {

String name;
int age; Class

...rest of the class...


}
Class Definition
• Example:

class Dog { Class

… Methods usually
go after the data
void bark() {
System.out.println("Woof!");
}
}

• A class may contain methods that describe the


behavior of objects
First Program

Run
Packages
• Groups related classes in the same category
• How to declare a class is part of a package?
package packagename;
package MyMathPackage;

• Unique name
• Hierarchal
package book.chapter1;
Packages
• Many packages in Java API
• javax.swing
• java.lang
• java.util
• Java.net
•…
• How to use a package?
import packagename; Only “Welcome”
class is imported.
import book.chapter1.Welcome;
import book.chapter1.*;
All classes in
chapter1 imported.
Run Program
JVM
• Usually: the source program must be recompiled
on another machine
• Because the object program can only run on a specific
machine.
• With Java:
• Compile the source program into bytecode.
• The bytecode can then run on any computer
• Which has Java Virtual Machine (JVM)
• A software that interprets Java bytecode.

• JVM
• Class loader
• Bytecode verifier
Program Detail

Enter main method

//This program prints Welcome to Java!


public class Welcome {
public static void main(String[] args) {
System.out.println("Welcome to Java!");
}
}
Configuration
• Set path to JDK bin directory
• set path=c:\Program Files\java\jdk1.7.0\bin
• Set classpath to include the current
directory
• set classpath=.
Reading Input from Console
Input and System.in
• interactive program: Reads input from the console.
• While the program runs, it asks the user to type input.
• The input typed by the user is stored in variables in the code.

• Can be tricky; users are unpredictable and misbehave.


• But interactive programs have more interesting behavior.

• Scanner: An object that can read input from many


sources.
• Communicates with System.in
• Can also read from files , web sites, databases, ...

48
Scanner syntax
• The Scanner class is found in the java.util package.
import java.util.Scanner;

• Constructing a Scanner object to read console input:


Scanner name = new Scanner(System.in);

• Example:
Scanner console = new Scanner(System.in);

49
Scanner methods
Method Description
nextInt() reads an int from the user and returns it
nextDouble() reads a double from the user
nextLine() reads a one-line String from the user
next() reads a one-word String from the user
Avoid when Scanner connected to System.in
• Each method waits until the user presses Enter.
• The value typed by the user is returned.

• prompt: A message telling the user what input to type.

System.out.print("How old are you? "); // prompt


int age = console.nextInt();
System.out.println("You typed " + age);

50
Scanner example
import java.util.Scanner;

public class UserInputExample {


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

System.out.print("How old are you? "); years 36


int age = console.nextInt();

int years = 65 - age;


System.out.println(years + " years until retirement!");
}
}

• Console (user input underlined): 29


How old are you?
36 years until retirement!

51
Scanner example 2
• The Scanner can read multiple values from one line.
import java.util.Scanner;
public class ScannerMultiply {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.print("Please type two numbers: ");
int num1 = console.nextInt();
int num2 = console.nextInt();
int product = num1 * num2;
System.out.println("The product is " + product);
}
}

• Output (user input underlined):


Please type two numbers: 8 6
The product is 48

52
Clicker 1 - Input tokens
• token: A unit of user input, as read by the Scanner.
• Tokens are separated by whitespace (spaces, tabs, new lines).
• How many tokens appear on the following line of input?
23 John Smith 42.0 "Hello world" $2.50 " 19"

A. 2 B. 6 C. 7

D. 8 E. 9

53
input tokens
•When a token is the wrong type, the
program crashes. (runtime error)
System.out.print("What is your age? ");
int age = console.nextInt();

Output:
What is your age? Timmy
java.util.InputMismatchException
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
...

54
Variables and Identifiers
Variable
• A variable stores a piece of data
int x =10;
• Variables are used to represent values that may
be changed in the program.
• Identifier
• Name of your variable
1. letters, digits, underscores (_), dollar signs ($)
2. Cannot start with a digit
3. Cannot be a reserved word Identifier
• E.g. cannot be: class X
Variable
23 Literal
Declaring Variables

• Example

int x = 0; // Declare x to be an
// integer variable;
// e.g. 101
double radius = 10.0; // Declare radius to
// be a double variable;
// e.g. 101.89
char y = ‘a’; // Declare y to be a
// character variable;
// e.g. ‘d’

• Do not forget that Java is case sensitive!


Variables
• If variables are of the same type, they can be declared together
• The variables are separated by commas. For example,
• int i, j, k; // Declare i, j, and k as int variables
• A variable must be declared before it can be assigned a value.
• A variable declared in a method must be assigned a value
before it can be used.
• Whenever possible, declare a variable and assign its initial
value in one step.
Variable
• Example

double radius;
// Compute the first area
radius = 1.0;
double area = radius * radius * 3.14159;

// Compute the second area


radius = 2.0;
area = radius * radius * 3.14159;
Identifiers
• Identifiers are the names that identify the elements such as classes,
methods, and variables in a program.
Identify and fix the errors in the following code:

1 public class Test {


2 public void Main(string[] args) {
3 int i = k + 2;
4 System.out.println(i);
5}
Lecture-02
Introduction to Java Programming
By
Dr. Bharati Mishra
Programming Constructs
Program Anatomy

• Comments
• Reserved words
• Modifiers
• Statements
• Blocks
• Classes
• Methods
• The main method
Comments

• 3 types of comments in Java


•Line comment //
• Example
• // This is a line comment!
•Paragraph comment /* */
• Example
• /* This is a paragraph comment.
It includes multiple lines. */
• JavaDoc comments (automatic
documentation) /** */
JavaDoc
• JavaDoc comments (automatic
documentation) /** */
• Tags starting with @
Reserved Words

• Reserved words (or keywords)


• Specific meaning to the compiler
• Cannot be used for other purposes
• Keywords in our previous examples
• class
• public
• static
• void
Modifiers

• A subset of keywords
• Specify the properties of the data,
methods, and classes and how they can
be used.
• Examples we have seen
• public
• static
• Other example modifiers
• private
• final
• abstract
• protected
Statement

• Represents an action or a sequence of


actions
• Every statement in Java ends with a
semicolon ;
• Examples

System.out.println("Hello World!");
a = 8 * 3.14;
Assignment Statements and Assignment
Expressions
• An assignment statement designates a value for a variable.
• An assignment statement can be used as an expression in Java.
• The equal sign (=) is used as the assignment operator.
• variable = expression;
• An expression represents a computation involving values, variables,
and operators that, taking them together, evaluates to a value.
Assignment Statements and Assignment
Expressions
int y = 1; // Assign 1 to variable y
double radius = 1.0; // Assign 1.0 to variable radius
int x = 5 * (3 / 2); // Assign the value of the expression to x
x = y + 1; // Assign the addition of y and 1 to x
double area = radius * radius * 3.14159; // Compute area

• You can use a variable in an expression.


• A variable can also be used in both sides of the = operator.
For example,
• x = x + 1;
Assignment Statements and Assignment
Expressions
• To assign a value to a variable, you must place the variable name to the left of the assignment
operator. Thus, the following statement is wrong:
• 1 = x; // Wrong

• Identify and Fix the error


1 public class Test {
2 public static void main(String[] args) {
3 int i = j = k = 2;
4 System.out.println(i + " " + j + " " + k);
5}
6}
Blocks

• A pair of braces in a program grouping


components of a program
Class

• The essential Java construct


• A template or blueprint for objects
• A program is defined by using one or
more classes.
Method

• A collection of statements that


performs a sequence of operations
• Might accept input
• Might provide output

Input
Input 2
1
Input
3

Output
Method

• What does it look like?


• Example
public returnType name(input1, input2, …)
{
// Statements;
}
Method

• What does it look like?


• Example

Return
Modifier Value name Input

public int addTwoNumbers(int a, int b)


{
int c = a + b;
return c;
}
Method

• What does it look like?


• Example

Return
Modifier Modifier Value name Input

public static void main(String[] args)


{
// Statements;
}
Named Constants
• A named constant is an identifier that represents a
permanent value.
• Value is constant, doesn’t change
• A constant must be declared and initialized in the
same statement
• Use “final” keyword to declare a value as constant

final datatype CONSTANTNAME = VALUE;

Example:

final double PI = 3.14159;


final int SIZE = 3;
Benefits of using Named constants
•There are three benefits of using constants:
(1) you don’t have to repeatedly type the same value if it is
used multiple times;
(2) if you have to change the constant value (e.g., from 3.14
to 3.14159 for PI), you need to change it only in a single
location in the source code; and
(3) a descriptive name for a constant makes the program
easy to read.
Conventions for naming variables, methods, and
classes.
• Use lowercase for variables and methods
• If a name consists of several words, concatenate them into one, making the first
word lowercase and capitalizing the first letter of each subsequent word.
• Capitalize the first letter of each word in a class name—for example, the class
names
ComputeArea and System.
• Capitalize every letter in a constant, and use underscores between words—for
example,
the constants PI and MAX_VALUE.
Numbers in More Detail ..
Numeric Data Types

• Different types of numeric data


Numeric Data Types
Sign bit

byte= 8 bits

short

int

long

float

double
Floating Point Numbers

• Integer calculations are precise.


• Calculations involving floating-point numbers are
approximated
• E.g. below displays 0.5000000000000001, not 0.5

System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);

• E.g. below displays 0.09999999999999998, not 0.1

System.out.println(1.0 – 0.9);
Literal

• A constant value appearing directly in the


program
• E.g.
int i = 34;
long x = 10000;
double d = 5.0;

• You can use append letters to indicate type

1000000L; //long
5.0f; //float
Literal

• A literal should fit in its variable


• The following example is wrong.

byte myVar = 10000;


• myVar can not hold this number.
• Byte range = [-128, 127] > 1000
Scientific Notation

• Floating point literals can be specified in


scientific notation, e.g.
• 1.23456e2
• 123.456 = 1.23456 * (10^2)
• Pitfall:
• Here “e” or “E” is NOT the natural logarithm’s base
(2.718). It is 10.
Numeric Operators

• Different types of numeric operators


Numeric Operators

• Be careful!
• 5 / 2 yields an integer 2
• 5.0 / 2 yields a double value 2.5
• Remainder can be very useful
• Even numbers % 2 = 0
• Today is Saturday and you and your friends are going to
meet in 10 days. What day is in 10 days?
Assignment
• Problem-01
(Compute the volume of a cylinder) Write a program that reads in the radius
and length of a cylinder and computes the area and volume using the following
formulas:
area = radius * radius * pi
volume = area * length

• Problem -02
(Sum the digits in an integer) Write a program that reads an integer between 0 and
1000 and adds all the digits in the integer. For example, if an integer is 932, the
sum of all its digits is 14.
Hint: Use the % operator to extract digits, and use the / operator to remove the
extracted digit. For instance, 932 % 10 = 2 and 932 / 10 = 93.
Lecture-03
Basics of Java Programming
By
Dr. Bharati Mishra
Agenda
∙ Evaluating Expressions
∙ Operator Precedence
∙ Case Study: Displaying the Current Time,
∙ Augmented Assignment Operators

∙ Increment and Decrement Operators

∙ Numeric Type Conversions


Arithmetic Expression to Java Expression
(3 + 4 * x) / 5 – 10 * (y - 5) * (a + b + c) / x +
9 * (4 / x + (9 + x) / y)
Arithmetic Expressions

• Operators have precedence


1. Parentheses ()
2. *, /, %
3. +,-
4. …
Shortcut Operators

• Shortcut operators for assignment

Operator Example Equivalent


+= i += 8 i = i + 8
-= f -= 8.0 f = f - 8.0
*= i *= 8 i = i * 8
/= i /= 8 i = i / 8
%= i %= 8 i = i % 8
++/--

• Increment, decrement operators


Operator Name Description

++var pre-increment The expression (++var) increments var by 1 and evaluates


to the new value in var after the increment.
var++ post-increment The expression (var++) evaluates to the original value
in var and increments var by 1.
--var pre-decrement The expression (--var) decrements var by 1 and evaluates
to the new value in var after the decrement.
var-- post-decrement The expression (var--) evaluates to the original value
in var and decrements var by 1.
++/--

• Increment, decrement operators


Conversions

• Example
byte i = 100;
long k = i * 3 + 4;
double d = i * 3.1 + k / 2;

• When having different types of operands


• Operands will be automatically converted to the
largest operand in the expression
Conversions

• Implicit casting (type widening)


int x = 3; double d = x;
• A small number fits easily in a large variable
• Explicit casting (type narrowing)
double d = 3.9;

int i = (int)d;

• 3.9 cannot be fit in an int, so fraction part is


truncated.
• Overflow: value too large to be stored

byte b = 300;
Tracing a Simple Program
Trace of Program
allocate memory for
public class ComputeArea { radius.
(it is a “variable”)
/** Main method */
public static void main(String[] args) {
double radius; radius no value
double area;

// Assign a radius
radius = 20;

// Compute area
area = radius * radius * 3.14159;

// Display results
System.out.println("The area for the circle of radius
"+
radius + " is " + area);
}
}
Trace of Program

public class ComputeArea {


/** Main method */
public static void main(String[] args) {
double radius; radius no value
double area; area no value

// Assign a radius
radius = 20; Allocate memory for
area.
// Compute area (It is a “variable”).
area = radius * radius * 3.14159;

// Display results
System.out.println("The area for the circle of radius
"+
radius + " is " + area);
}
}
Trace of Program

public class ComputeArea { Assign value to


radius
/** Main method */
public static void main(String[] args) {
double radius; radius 20
double area; area no value

// Assign a radius
radius = 20;

// Compute area
area = radius * radius * 3.14159;

// Display results
System.out.println("The area for the circle of radius
"+
radius + " is " + area);
}
}
Trace of Program

public class ComputeArea {


/** Main method */
public static void main(String[] args) {
double radius; radius 20
double area; area 1256.636

// Assign a radius
radius = 20; Compute area and
assign it to the
variable
// Compute area
area = radius * radius * 3.14159;

// Display results
System.out.println("The area for the circle of radius
"+
radius + " is " + area);
}
}
Other Data Types in Detail ..
Character Type

• char ch = ‘a’;
• ASCII
• Initial encoding
• Unicode
• More recent encoding, allowing international
encoding
• A 16-bit encoding scheme, preceded by \u,
expressed in four hexadecimal numbers that run
from '\u0000' to '\uFFFF'.
• char ch = ‘\u0003’;
Character Type

• How to declare?
• char letter = 'A'; (ASCII)
• char numChar = '4'; (ASCII)
• char letter = '\u0041'; (Unicode)
• char numChar = '\u0034'; (Unicode)
• Representing a numerical code (e.g. ‘a’=97)
• You can use +/- on char

char ch = 'a';
System.out.println(++ch);
Character Type

• Java characters use Unicode


• Supports display of written texts in the world’s
diverse languages.

Unicode \u03b1 \u03b2 \u03b3


for three Greek letters
Escape Characters

• Special characters called “escape” characters


Description Escape Sequence Unicode
Backspace \b \u0008
Tab \t \u0009
Linefeed \n \u000A
Carriage return \r \u000D
Backslash \\ \u005C
Single Quote \' \u0027
Double Quote \" \u0022
Escape Characters

• Example 1
• System.out.println(“Java is fun!”);
• Output: Java is fun!
• Example 2
• System.out.println(“Java is \n fun!”);
• Output: Java is
fun!
• Equivalent to:
• System.out.println(“Java is”);
• System.out.println(“fun!”);
String Type

• Char type is one character


• E.g. ‘a’
• String type is sequence of characters
• String x = “Java is fun”;
• Not a primitive type!
• A predefined class in Java
• Reference type (more later in Chapter 7)
String Type

• Concatenate strings
1. String message = "Welcome " + "to " + "Java";
• //message becomes “Welcome to Java”
2. String s1 = "Chapter" + 2;
• // s1 becomes Chapter2
3. String s2 = "Supplement" + 'B';
• // s2 becomes SupplementB
Converting Strings

• Equivalent class for each data type


• Byte, Short, Integer, Long, Float, Double, Character
• Use the following method to convert from String
int x = Integer.parseInt(“85”);

• Use the following method to convert from String


double y=Double.parseDouble(“85.7”);
Programming Style
Programming Style

• Appropriate Comments
• Naming Conventions
• Proper Indentation and Spacing Lines
• Block Styles
Programming Style

• Comment is important
• Documenting your program
• Appropriate Comments
• Include a summary at the beginning of the program
• what the program does
• its key features
• its supporting data structures
• For this class:
• your name, class section, date, and a brief description at the
beginning of the program.
Programming Style

• Choose meaningful and descriptive names, not


cryptic names!
• Variables and method names
• Use lowercase.
• If the name consists of several words, capitalize the
first letter of each subsequent word in the name.
• computeArea()
• Class names
• Capitalize the first letter of each word in the name
• BankAccount
• Constants
• Capitalize all letters in constants, use underscores
• MAX_VALUE
Programming Style

• Indentation
• Blocking styles
• Spacing
• Use blank line to separate segments of the code.

Indentation
Programming Errors
Programming Errors

• Syntax Errors
• Detected by the compiler
• E.g. “iNT x;” instead of “int x;”
• Runtime Errors
• Causes the program to abort
• E.g. x= 3/0;
• Logic Errors
• Produces incorrect result
• Tax = 1.0 * income;
Syntax Errors

• Syntax Errors

public class ShowSyntaxErrors {


public static void main(String[] args) {
i = 30;
System.out.println(i + 4);
}
}
Runtime Errors

• Runtime Errors
public class ShowRuntimeErrors {
public static void main(String[] args) {
int i = 1 / 0;
}
}
Logical Errors

• Logical Errors
• Error in design of program
• E.g. using the wrong formula for computing the area of
a circle
Debugging

• Logical Errors are called “bugs”


• The process of finding and correcting errors is
called debugging.
• narrow down to where the bug is located
1. hand-trace the program (read your program)
• Difficult
2. insert print statements to show the values of the
variables
• Still not very effective
3. Use a debugger utility
Debugging

• History of term “bug”

Admiral Grace
Hopper
Debugging

• Debugger: the program for debugging


• Usually part of IDE
• It allows you to
• Execute a single statement at a time
• Trace into or stepping over a method
• Set breakpoints
• Display variables
Lecture-04
Selection
By
Dr. Bharati Mishra
Agenda
• boolean Data Type
• if Statements
• Two-Way if-else Statements
• Nested if
• Multi-Way if-else Statements
• Common Errors and Pitfalls
• Generating Random Numbers
• Case Study:
• Computing Body Mass Index,
• Computing Taxes
• Logical Operators
• Case Study:
• Determining Leap Year, Lottery
boolean Data Type

• Another primitive data type in Java


• Only has two values
• true
• false
• Examples
• boolean test = false;
• boolean checked = true;
• Usually used for checking conditions
Comparison Operators

• Six comparison operators in Java

Operator Name
< Less than
<= Less than or equal to
> Greater than
>= Greater than or equal to
== Equal to
!= Not equal to
Class vs. Primitive Type

• Primitive data type


• Predefined range
• A primitive variable stores the value
• Reference data type
• Class, Array [will be discussed later]
• Size is not predefined!
• stores a “reference” to the actual object

int x = 10; Integer y = new Integer(10);

10 Integer
….
y ….
x
Comparison Operators

• Be careful about ==
• Primitive data type:
• Compares the value
• Reference data type:
• Compares the references (memory address)!
• So only use with primitive data types
• E.g. if x and y are String
• x==y will not always return the correct result!
• Instead use String.compare(x,y)
• In general, use equals() to compare two objects
• E.g. a.equals(b)
Comparison Operators

• Result of comparison is boolean


• boolean x = (3 > 2);
• x is true
• boolean y = (1 > 2);
• y is false
Program
• Create a program to let a first grader practice
additions. The program randomly generates two
single-digit integers number1 and number2 and
displays a question such as:

“What is 7 + 9?”

to the student. After the student types the answer,


the program displays a message to indicate whether
the answer is true or false.
“if” statement
One way if
• Checks for a simple condition
• It is written as
if (boolean-expression) {
statement(s);
}

• E.g.
if (radius >= 0) {
area = radius * radius * PI;
}
One way if
• Be careful!
If Program
• Write a program that prompts the user to enter an
integer. If the number is a multiple of 5, print
HiFive. If the number is divisible by 2, print HiEven.
Two-way if
• If you get here by 10:00 am, then we can have
brunch, else we can go for lunch.

if (boolean-expression) {
statement(s)-for-the-true-case;
}
else {
statement(s)-for-the-false-case;
}
Two-way if
• Example

if (radius >= 0) {
area = radius * radius * 3.14159;
System.out.println("The area is: “ + area);
}
else {
System.out.println("Negative input");
}
Multiple if-else
• else if is used for checking multiple conditions

if (score >= 90.0) if (score >= 90.0)


grade = 'A'; grade = 'A';
else if (score >= 80.0) else
grade = 'B'; if (score >= 80.0)
else if (score >= 70.0) grade = 'B';
grade = 'C'; else
else if (score >= 60.0) if (score >= 70.0)
grade = 'D'; grade = 'C';
else else
grade = 'F'; if (score >= 60.0)
grade = 'D';
else
grade = 'F';
Trace
• Let’s trace a program!

Suppose score is 70.0


The condition is false

if (score >= 90.0)


grade = 'A';
else if (score >= 80.0)
grade = 'B';
else if (score >= 70.0)
grade = 'C';
else if (score >= 60.0)
grade = 'D';
else
grade = 'F';
Trace
• Let’s trace a program!

Suppose score is 70.0

if (score >= 90.0) The condition is false


grade = 'A';
else if (score >= 80.0)
grade = 'B';
else if (score >= 70.0)
grade = 'C';
else if (score >= 60.0)
grade = 'D';
else
grade = 'F';
Trace
• Let’s trace a program!

Suppose score is 70.0

if (score >= 90.0)


grade = 'A';
else if (score >= 80.0) The condition is true!
grade = 'B';
else if (score >= 70.0)
grade = 'C';
else if (score >= 60.0)
grade = 'D';
else
grade = 'F';
Trace
• Let’s trace a program!

Suppose score is 70.0

if (score >= 90.0)


grade = 'A';
else if (score >= 80.0)
grade = 'B'; The grade is C!
else if (score >= 70.0)
grade = 'C';
else if (score >= 60.0)
grade = 'D';
else
grade = 'F';
Trace
• Let’s trace a program!

Suppose score is 70.0

if (score >= 90.0)


grade = 'A';
else if (score >= 80.0)
grade = 'B';
else if (score >= 70.0) exit.
grade = 'C';
else if (score >= 60.0)
grade = 'D';
else
grade = 'F';
Caution on if-else

• Note! The else clause matches the most recent if


clause in the same block.

• What is the printed on screen?


• Nothing!
Caution on if-else

• Nothing is printed from the preceding statement.


To force the else clause to match the first if
clause, you must add a pair of braces:
int i = 1;
int j = 2;
int k = 3;
if (i > j) {
if (i > k)
System.out.println("A");
}
else
System.out.println("B");

• This prints B.
Tips

• Some tips
Program

• This time program randomly generates two


single-digit integers number1 and number2 such
that (number1 > number2) and displays a
question such as

“What is 9 – 2?” to the student.


Logical Operators
Logical Operators

• What if we need more complex conditions


composed of “and/or/..”?

Operator Name
! not
&& and
|| OR
^ Exclusive OR
Logical Operators

• Not (!) operator


Logical Operators

• And (&&) operator


Logical Operators

• Or (||) operator
Logical Operators

• Exclusive Or (^) operator


Program

• A program that checks whether a number is


• divisible by 2 and 3
• divisible by 2 or 3
• divisible by 2 or 3 but not both.
Common Errors

• Adding a semicolon at the end of an if clause is a


common mistake.
if (radius >= 0); Wrong
{
area = radius*radius*PI;
System.out.println( "The area for the circle of radius "
+ radius + " is " + area);
}

• Equivalent to
if (radius >= 0) { };
other statements
• What is the output?
• Always prints the area, even for negative numbers
Case Study-01

• Write a program that randomly generates a lottery


of a two-digit number, prompts the user to enter a
two-digit number, and determines whether the
user wins according to the following rule:
• If the user input matches the lottery in exact
order, the award is $10,000.
• If the user input matches the lottery, the award is
$3,000.
• If one digit in the user input matches a digit in the
lottery, the award is $1,000.
Case Study -02
The United States federal personal income tax is calculated based on filing status and taxable
income. There are four filing statuses: single filers, married filing jointly or qualified
widow(er), married filing separately, and head of household. The tax rates vary every year.
Table below shows the rates for 2009. If you are, say, single with a taxable income of $10,000,
the first $8,350 is taxed at 10% and the other $1,650 is taxed at 15%, so, your total tax is
$1,082.50.
Case Study -03 : Determining Leap Year
•A year is a leap year if it is divisible by 4 but not
by 100, or if it is divisible by 400.
Lecture-05
Switch Statements

By
Dr. Bharati Mishra
Switch Statements
Switch Statement

• Tax Program
switch (status) {
case 0:
//compute taxes for single filers;
break;
case 1:
//compute taxes for married file jointly;
break;
case 2:
//compute taxes for married file separately;
break;
case 3:
//compute taxes for head of household;
break;
default: System.out.println("Errors: invalid status");
}
Switch Statement

• Tax Program
Switch Statement
• A closer look switch (switch-expression) {
case value1: statement(s)1;
• value1, ... valueN are break;
constant case value2: statement(s)2;
• the same data type as break;
the value of the …
switch-expression.
case valueN: statement(s)N;
break;
default: statement(s)-for-default;
}

• Statements are executed when the value in the


case statement matches the value of the
switch-expression.
Switch Statement
switch (switch-expression) {
• A closer look
case value1: statement(s)1;
Using break is optional, but it break;
should be used at the end of case value2: statement(s)2;
each case in order to terminate break;
the remainder of the switch …
statement. If the break
case valueN: statement(s)N;
statement is not present, the
next case statement will be break;
executed. default: statement(s)-for-default;
}

• The default case, which is optional, can be used to


perform actions when none of the specified cases
matches the switch-expression.
Program Trace

• Example
Suppose ch is 'a':

‘a’
switch (ch) {
case 'a': System.out.println(ch);
case 'b': System.out.println(ch);
case 'c': System.out.println(ch);
}
Program Trace

• Example

ch is 'a':

switch (ch) {
case 'a': System.out.println(ch);
case 'b': System.out.println(ch);
case 'c': System.out.println(ch);
}
Program Trace

• Example

Execute this line.

switch (ch) {
case 'a': System.out.println(ch);
case 'b': System.out.println(ch);
case 'c': System.out.println(ch);
}
Program Trace

• Example

Execute this line.

switch (ch) {
case 'a': System.out.println(ch);
case 'b': System.out.println(ch);
case 'c': System.out.println(ch);
}
Program Trace

• Example

switch (ch) {
case 'a': System.out.println(ch);
case 'b': System.out.println(ch);
case 'c': System.out.println(ch);
}

Execute this line.


Program Trace II

• Example

Suppose ch is ‘a’.

switch (ch) {
case 'a': System.out.println(ch); break;
case 'b': System.out.println(ch); break;
case 'c': System.out.println(ch); break;
}
Program Trace II

• Example

ch is ‘a’.

switch (ch) {
case 'a': System.out.println(ch); break;
case 'b': System.out.println(ch); break;
case 'c': System.out.println(ch); break;
}
Program Trace II

• Example

Execute this line.

switch (ch) {
case 'a': System.out.println(ch); break;
case 'b': System.out.println(ch); break;
case 'c': System.out.println(ch); break;
}
Program Trace II

• Example

Execute this line.

switch (ch) {
case 'a': System.out.println(ch); break;
case 'b': System.out.println(ch); break;
case 'c': System.out.println(ch); break;
}
Program Trace II

• Example

switch (ch) {
case 'a': System.out.println(ch); break;
case 'b': System.out.println(ch); break;
case 'c': System.out.println(ch); break;
}

End of switch.
Conditional Statement
Conditional Statement

• Conditional statement as
(boolean-expression) ? expression1 : expression2

if (x > 0)
y = 1; y = (x > 0) ? 1 : -1;
else
y = -1;
Conditional Statement

if (num % 2 == 0)
System.out.println(num + “is even”);
else
System.out.println(num + “is odd”);

Same as:

System.out.println(
(num % 2 == 0)? num + “is even” : num + “is odd”);
Operator Precedence and Associativity
Operator Precedence and Associativity
Operator precedence and associativity determine the order in
which operators are evaluated.
Example:-

3 + 4 * 4 > 5 * (4 + 3) – 1 && (4 - 3 > 5)


• If operators with the same precedence are next to each other, their associativity determines
the order of evaluation.
Operator Precedence and Associativity
Operator Precedence

1. var++, var--
2. +, - (Unary plus and minus), ++var,--var
3. (type) Casting
4. ! (Not)
5. *, /, % (Multiplication, division, and remainder)
6. +, - (Binary addition and subtraction)
7. <, <=, >, >= (Comparison)
8. ==, !=; (Equality)
9. ^ (Exclusive OR)
10. && (Conditional AND) Short-circuit AND
11. || (Conditional OR) Short-circuit OR
12. =, +=, -=, *=, /=, %= (Assignment operator)
Precedence Rules

• All binary operators except “assignment”


operators are left-associative.
a–b+c–d
is equivalent to
((a – b) + c) – d
• Assignment operators are right-associative.
Therefore, the expression
a = b += c = 5
is equivalent to
a = (b += (c = 5))
Case-01
Now let us write a program to find out the Chinese Zodiac sign for a given year. The
Chinese Zodiac is based on a twelve-year cycle, with each year represented by an animal—
monkey, rooster, dog, pig, rat, ox, tiger, rabbit, dragon, snake, horse, or sheep—in this cycle,
as shown in Figure.
Note that year % 12 determines the Zodiac sign. 1900 is the year of the rat because 1900
% 12 is 4. Listing 3.9 gives a program that prompts the user to enter a year and displays the

animal for the year.


Lecture-06
By
Dr. Bharati Mishra
Topics
• Common Mathematical Functions
• Character Data Type and Operation
• The String Type
• Case Study, Formatting Console Output
Math Class in Java

• Java includes 8 primitive data types


• byte, short, int, long, float, double, char, boolean
• The Math class contains static methods for common mathematical
operations (for which an operator does not exist in Java)
• Call those methods: Math.<MethodName>
Math.pow(2, 5);

3
Java's Math class
Method name Description
Math.abs(value) absolute value
Math.ceil(value) moves up to ceiling
Math.floor(value) moves down to floor
Math.log10(value) logarithm, base 10
Math.max(value1, value2) larger of two values
Math.min(value1, value2) smaller of two values
Math.pow(base, exp) base to the exp power
Math.random() random double between 0 and 1
Math.rint(value) Round int, nearest whole number
Math.sqrt(value) square root
Math.sin(value) sine/cosine/tangent of
Math.cos(value) an angle in radians
Math.tan(value) Constant Description
Math.toDegrees(value) convert degrees to Math.E 2.7182818...
Math.toRadians(value) radians and back
Math.PI 3.1415926...

4
No output?
• Simply calling these methods produces no visible result.
Math.pow(3, 4); // no output

• Math method calls use a Java feature called return values


that cause them to be treated as expressions.
• The program runs the method, computes the answer, and
then "replaces" the call with its computed result value.
Math.pow(3, 4); // no output
81.0; // no output
• To see the result, we must print it or store it in a variable.
double result = Math.pow(3, 4);
System.out.println(result); // 81.0

5
Calling Math methods
Math.methodName(parameters)
• Examples:
double squareRoot = Math.sqrt(121.0);
System.out.println(squareRoot); // 11.0
int absoluteValue = Math.abs(-50);
System.out.println(absoluteValue); // 50
System.out.println(Math.min(3, 7) + 2); // 5

• The Math methods do not print to the console.


• Each method produces ("returns") a numeric result.
• The results are used as expressions (printed, stored, etc.).

6
Return
• return: To send out a value as the result of a method.
• The opposite of a parameter:
• Parameters send information in from the caller to the method.
• Return values send information out from a method to its caller.
• A call to the method can be used as part of an expression.

-42 Math.abs(-42)

42
main
2.71

3
Math.round(2.71)

7
Why return and not print?

• It might seem more useful for the Math methods to print


their results rather than returning them. Why don't they?
• Answer: Returning is more flexible than printing.
• We can compute several things before printing:
double pow1 = Math.pow(3, 4);
double pow2 = Math.pow(10, 6);
System.out.println("Powers are " + pow1 + " and " + pow2);

• We can combine the results of many computations:


double k = 13 * Math.pow(3, 4) + 5 - Math.sqrt(17.8);

8
• What is output by the following code?
double a = -1.9;
double b = 2.25;
System.out.print( Math.floor(a) +
" " + Math.ceil(b) + " " + a);
A. 3.0
B. -2.0 3.0 -2.0
C. -1.0 3.0 -1.0
D. -1 3 -1.9
E. -2.0 3.0 -1.9

9
Math questions
• Evaluate the following expressions:
Math.abs(-1.23)
Math.pow(3, 2)
Math.pow(10, -2)
Math.sqrt(121.0) - Math.sqrt(256.0)
Math.round(Math.PI) + Math.round(Math.E)
Math.ceil(6.022) + Math.floor(15.9994)
Math.abs(Math.min(-3, -5))
• Math.max and Math.min can be used to bound numbers.
Consider an int variable named age.
What statement would replace negative ages with 0?
What statement would cap the maximum age to 40?

10
Quirks of real numbers
• Some Math methods return double or other non-int
types.
int x = Math.pow(10, 3); // ERROR: incompat. types

• Some double values print poorly (too many digits).


double result = 1.0 / 3.0;
System.out.println(result); // 0.3333333333333
• The computer represents doubles in an imprecise way.
System.out.println(0.1 + 0.2);

• Instead of 0.3, the output is 0.30000000000000004


11
• What is the output of the following code?
int x = 5;
int y = 7;
System.out.print(m(x, y) + " " + x + " " + m(y, x));

public static int m(int x, int y) {


x += 2;
System.out.print(x + " ");
y -= 2;
return x * y;
}
A. 7 9 35 5 27
B. 7 7 35 7 27
C. 7 5 9 27 35
D. 35 7 5 9 27
E. None of A - D are correct

12
Case Study-01
• In physics, the displacement of a moving body represents
its change in position over time while accelerating.
• Given initial velocity v0 in m/s, acceleration a in m/s2, and
elapsed time t in s, the displacement of the body is:
• Displacement = v0 t + ½ a t 2
• Write a method displacement that accepts v0, a, and
t and computes and returns the change in position.
• example: displacement(3.0, 4.0, 5.0) returns
65.0

13
Case Study-02
• Find the angles of a triangle, given the vertices of the triangle.
Character

• Java provides a wrapper class for each primitive


data type
• All in java.lang package
• Primitive data values can be treated as objects
• char
• Primitive data type
• Character class
• Wrapper
Character

• Character class
Character

• Character class
Character charObject = new Character('b');

▪ charObject.compareTo(new Character('a')) returns 1


▪ charObject.compareTo(new Character('b')) returns 0
▪ charObject.compareTo(new Character('c')) returns -1
▪ charObject.compareTo(new Character('d') returns –2
▪ charObject.equals(new Character('b')) returns true
▪ charObject.equals(new Character('d')) returns false
String
String
• String is a reference type (class)

//String is a class
String message = new String("Welcome to Java");

//Since strings are used frequently, Java provides a //shorthand


initializer for creating a string:
String message = "Welcome to Java";

//You can also create a string from an array of


// characters (char)
char[] charArray = {‘W’, ‘e’, ‘l’, ‘c’, ‘o’, ‘m’, ‘e’};
String message = new String(charArray);
String
• A String object is immutable
• i.e. its contents cannot be changed.
• Does the following code change the contents of
the string?

String s = "Java";
s = "HTML";
Trace Code
String s = "Java";
s = "HTML";
Interned String
• To improve efficiency and save memory:
• JVM uses a unique instance for string literals with
the same character sequence.
• Such an instance is called interned.
Interned String
If you use the string initializer, no new object is
created, if the interned object is already created.
String Comparison

To compare strings, do not use ==


String Comparison

Difference between “==“ vs. “equals()”

String s1 = new String("Welcome");


String s2 = "Welcome";

if (s1.equals(s2))
{
// s1 and s2 have the same contents
}

if (s1 == s2)
{
// s1 and s2 have the same reference
}
String Comparison

To compare strings, do not use >=, <=

String s1 = new String("Welcome");


String s2 = "Welcome";

if (s1.compareTo(s2) > 0)
{
// s1 is greater than s2
// lexicographically, i.e. unicode order
}
else if (s1.compareTo(s2) == 0)
{
// s1 and s2 have the same contents
}
else
// s1 is less than s2
String

• Length
• Retrieving individual characters
• Concatenating string
String

• Finding string length using the length()


method:

String message = "Welcome";


int msgLength= message.length();
//7
String

• Retrieving individual characters in a string:


• Do not use message[0]
• Use message.charAt(index)
• Index starts from 0
Concatenation

1. String concatenation
String s3 = s1.concat(s2);

2. String concatenation
String s3 = s1 + s2;

• Both have the same effect


s1 + s2 + s3 + s4 + s5 =
(((s1.concat(s2)).concat(s3)).concat(s4)).concat(s5);
Reading a String
• next() method on Scanner object is used
• Example:
Scanner input = new Scanner(System.in);
System.out.print("Enter three words separated by spaces: ");
String s1 = input.next();
String s2 = input.next();
String s3 = input.next();
System.out.println("s1 is " + s1);
System.out.println("s2 is " + s2);
System.out.println("s3 is " + s3);
Reading a Line
•The next() method reads a string that ends with a whitespace
character.
• nextLine() method to read an entire line of text.
Scanner input = new Scanner(System.in);
System.out.println("Enter a line: ");
String s = input.nextLine();
System.out.println("The line entered is " + s);
Reading a character from Console
Scanner input = new Scanner(System.in);
System.out.print("Enter a character: ");
String s = input.nextLine();
char ch = s.charAt(0);
System.out.println("The character entered is " + ch);
Extraction

• String extraction
Extraction

• You can extract a single character from a string


using the charAt() method.
• You can extract a substring from a string using
the substring() method.
String Message = "Welcome to Java";
String s2 = Message.substring(0, 11) + "HTML";
More

• Converting, replacing, and splitting String


More

• Converting, replacing, and splitting String

String s1 = "Welcome".toLowerCase();
//s1 is a new String: “welcome”
String s2 = "Welcome".toUpperCase();
//s2 is a new string: “WELCOME”
String s3 = " Welcome ".trim();
//s3 is a new string: “Welcome”
String s4 = "Welcome".replace('e', 'A');
//s4 is a new string: “WAlcomA”
String s5 = "Welcome".replaceFirst("e", "AB");
//returns a new string, WABlcome.
String s6 = "Welcome".replaceAll("e", "AB");
//s6 is a new string: “WABlcomAB”
String s7 = "Welcome".replaceAll("el", "AB");
//s7 is a new string: “WABlcome”
More

• The following code displays “Java HTML Perl”

String[] tokens = "Java#HTML#Perl".split("#“,0);

for (int i = 0; i < tokens.length; i++)


System.out.print(tokens[i] + " ");
More

• You can match, replace, or split a string by


specifying a pattern.
• This is an extremely useful and powerful feature,
commonly known as regular expression.
• Regular expression is complex to beginning
students. For this reason, only two simple
patterns are used in this section.
Regular Expression

• Regular expression:

"Java".matches("Java");
"Java".equals("Java");

"Java is fun".matches("Java.*");
"Java is cool".matches("Java.*");
Regular Expression

• The replaceAll(), replaceFirst(), and split()


methods can be used with a regular expression.
Regular Expression

• For example, the following statement returns a


new string that replaces $, +, or # by the string
NNN.

String s = "a+b$#c".replaceAll("[$+#]", "NNN");


System.out.println(s);

• Here the regular expression [$+#] specifies a


pattern that matches $, +, or #.
• So, the output is “aNNNbNNNNNNc”.
Regular Expression

• The following code splits the string into an array


of strings delimited by some punctuation marks.
Find
• Finding a Character or a Substring in a String
Find
• "Welcome to Java".indexOf('W')
• returns 0.
• "Welcome to Java".indexOf('x')
• returns -1.
• "Welcome to Java".indexOf('o', 5)
• returns 9.
• "Welcome to Java".indexOf("come")
• returns 3.
• "Welcome to Java".indexOf("Java", 5)
• returns 11.
• "Welcome to Java".indexOf("java", 5)
• returns -1.
• "Welcome to Java".lastIndexOf('a')
• returns 14.
Conversions

• A String is not an array!


• But, can be converted.
Conversions

• The String class provides several static valueOf ()


methods for converting a character, an array of
characters, and numeric values to strings.
• These methods have the same name valueOf with
different argument types.
• For example, to convert a double value to a string,
use String.valueOf(5.44)
• The return value is string “5.44”.
Numbers & Strings

• The String class provides several static valueOf ()


methods
Program

• Checking whether a string is a palindrome:


• A string that reads the same forward and backward.
• Dad, Mom, noon

CheckPalindrome Run
StringBuilder & StringBuffer
StringBuilder

• The StringBuilder/StringBuffer class is


an alternative to the String class.
• In general, a StringBuilder/StringBuffer can be
used wherever a string is used.
• StringBuilder/StringBuffer is more flexible than
String.
• You can add, insert, or append new contents into a
string buffer
• whereas the value of a String object is fixed once the
string is created.
StringBuilder

• The StringBuilder class


StringBuilder
StringBuilder

• The StringBuilder class


StringBuffer

• StringBuffer is very similar to StringBuilder


• It has synchronized methods
• Use it in mutli-threaded applications
Program

• Ignoring non-alphanumeric characters when


checking palindromes

PalindromeIgnoreNonAlphanumeric Run
Command Line Arguments
More on main

• You can call a regular method by passing actual


parameters. Can you pass arguments to main?
• Of course, yes. For example, the main method in
class B is invoked by a method in A, as shown
below:
Command Line args

• Command line arguments

class TestMain
{
public static void main(String[] args)
{
...
}
}
Command Line args

• In the main method, get the arguments from


args[0], args[1], ..., args[n]
• which corresponds to arg0, arg1, ..., argn in the
command line.
Program
• Write a program that will perform binary
operations on integers. The program receives
three parameters: an operator and two integers.

java Calculator 2 + 3

Calculator java Calculator 2 - 3

java Calculator 2 / 3
Run
java Calculator 2 “*” 3 61
Formatting Output
Formatting Output

• The methods println() and print() do not allow for


easy formatting
• Instead use printf()
System.out.printf ("format string", dataValue1, dataValue2, ....);
• One format specifier for every data value.
• Format specifiers always begin with the % symbol.
• The format string and all data values are separated
by commas ( NO + signs).
• The data values are NOT within double quotes.
Formatting Output

• %s s stands for a string


• %f stands for floating point number
• System.out.printf("%s, %s", "Hello", "World!");
• Output: “Hello, World!”
• System.out.printf(“%.1f pounds” ,28.8968);
• Output: “28.8 pounds”
Formatting Output

Specifier Output Example


%b a boolean value true or false
%c a character 'a'
%d a decimal integer 200
%f a floating-point number 45.460000
%e a number in scientific notation 4.556000e+01
%s a string "Java is cool"
Formatting Specifier

• Format specifiers in more detail

% flag width .precision type

Maximum number
A flag (such as of digits after
Tells the decimal point
compiler to - to left justify)
expect a
specifier … Minimum
number of Data type (e.g. %f)
characters to
show
Width

• Width: minimum number of characters to show


• If the string representation of the value does not
fill the minimum length, the field will be
left-padded with spaces.
• If the converted value exceeds the minimum
length, however, the converted result will not be
truncated.
• Example
• System.out.printf("%6d",52)
• Output: " 52" (four spaces on the left)
Flag

• By default, data is right justified.


• If a dash - follows the % symbol of a format
specifier, then the data value will be left justified.
The - is called a format flag.
• Example
• System.out.printf("%-6d",52)
• Output: “52 " (four spaces on the right)
Precision

• How many digits after decimal point

double percentage = 99.3456789;


System.out.printf("%10.4f”, percentage );

• Output: “ 99.3456”
Lecture-10
By
Dr. Bharati Mishra
Loops
Motivation
• Suppose we want to show “Java is fun!” 100 times.
How do we do that?
• Repeat the following statement 100 times!?

System.out.println("Welcome to Java!");
Naïve Solution
• Naïve solution

System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
100
times! …


System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
System.out.println("Welcome to Java!");
Better Solution
• Better solution
• Using loop

int count = 0;
while (count < 100) {
System.out.println("Welcome to Java");
count++;
}
Why Loops?
1. To automate the repetition of calculations
E.g. compute the profit for “a number of different months”
of a company's sale

2. To iterate through data and test for certain


condition
E.g. Checking input data, until user wants to “quit”

3. To keep attempting for some operation


E.g obtaining data from a remote computer over a
network) until we succeed
while Loop
while Loop
while(condition)
{
statement;
}
1. If the condition is true, the statement is
executed; then the condition is evaluated again

2. The statement is executed over and over until
the condition becomes false.
3. When the loop finishes, control passes to the
next instruction in the program, following the
closing curly brace of the loop.
while

int count = 0;
while (loop-condition) {
while (count < 100) {
// loop-body; System.out.println("Welcome to Java!");
Statement(s); count++;
} }
Trace Program

Initialize count

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}
Trace Program

(count < 2) is true

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}
Trace Program

Print “Welcome to Java!”

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}
Trace Program

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}

count is now 1.
Trace Program

(count < 2) is still true.

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}
Trace Program

Print “Welcome to Java!”

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}
Trace Program

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}

count is now 2.
Trace Program

(count < 2) is now false.

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}
Trace Program

int count = 0;
while (count < 2) {
System.out.println("Welcome to Java!");
count++;
}

Loop exit
Caution!
• No ; at the end of while
No ; here!

int count = 0;
while (count < 100)
{
System.out.println("Welcome to Java!");
count++;
}
Caution!
• The body of a while loop must eventually make
the condition false
• If not, it is an infinite loop, which will execute until
the user interrupts the program!

int count = 1;
while (count > 0)
{
System.out.println("Welcome to Java!");
count++;
}
CAUTION!
• Don’t use floating-point values for equality
checking in a loop control!
• Floating-point values are approximations

double item = 1.0;


while (item != 0.0) {
// No guarantee item will be 0
item -= 0.1;
}

• There is no guarantee that item will be exactly


0: actually an infinite loop!
Tip
• Avoid using literals directly in code as much as
possible (good programming style)

int count = 0;
final int REPEATS = 100;
while (count < REPEATS )
{
System.out.println(“Java");
count++;
}
System.out.println(REPEATS + “ Times” );
Tip
• To repeat a loop 10 times, you generally write a
loop “not from 1 to 10”, but “from 0 to 9”.
• All counting in Java tends to start at zero rather
than one. This is a convention that most Java
programmers adopt.
• Again: good programming style
Program
• Write a program that randomly generates an
integer between 0 and 100, inclusive. The
program prompts the user to enter a number
continuously until the number matches the
randomly generated number. For each user
input, the program tells the user whether the
input is too low or too high, so the user can
choose the next input intelligently.

GuessNumberOneTime

GuessNumber
Program
• Write a program that prompts the user to enter
two positive integers and finds their greatest
common divisor.

GreatestCommonDivisor Run
Program
• Suppose that the tuition for a university is $10,000
this year and tuition increases 7% every year. In
how many years will the tuition be doubled?

FutureTuition Run
Program
• Often the number of times a loop is executed is
not predetermined. You may use an input value
to signify the end of the loop. Such a value is
known as a sentinel value.

• Write a program that reads and calculates the


sum of an unspecified number of integers. The
input 0 signifies the end of the input.

SentinelValue
Program
• A sentinel-controlled loop can be implemented
using a confirmation dialog. The answers Yes or No
to continue or terminate the loop. The template of
the loop may look as follows

int option = 0;
while (option == JOptionPane.YES_OPTION) {
System.out.println("continue loop");
option = JOptionPane.showConfirmDialog(null, "Continue?");
}

SentinelValueUsingConfirmationDialog Run
Program
• This example gives a program that generates five
questions and reports the number of the correct
answers after a student answers all five
questions.

SubtractionQuizLoop
do-while Loop
do-while
• Will be executed at least once

do {
// Loop body;
Statement(s);
} while (loop-condition);
Caution!
• ; at the end of while

int count = 0;
do
{
System.out.println("Welcome to Java!");
count++;
} while (count < 100) ;

; here!
CAUTION!
• Do NOT add a semicolon at the end of the while
clause:

int i=0; X int i=0;


while (i < 10); do {
{ System.out.println(i);
System.out.println(i); i++;
i++; } while (i<10);
}

• BUT in case of do-while ; is required.


for Loop
for loop
int count = 0;
while (count < 10)
{
System.out.println("Welcome to Java!");
count++;
}

for(int count =0; count < 10; count ++)


{
System.out.println("Welcome to Java!");
}
for loop
for (initial-action;
continuation-condition;
action-after-each-iteration)
{
// loop body….
}

int i;
for (i = 0; i < 100; i++) {
System.out.println("Welcome to Java!");
}
Tip
• It is common to declare the loop variable at the
start of the for loop itself:

for( int Count = 0; Count < 10; Count++ )


{
....;
}
for loop
More Tips
• The initial-action statement is carried out once
only, at the start of the first time that the loop is
entered.
• The continuation-condition is tested before each
execution of the body of the loop, including a test
before the very first execution of the loop.
• The third expression (i.e
action-after-each-iteration) is a statement
executed after every execution of the loop body,
before the next test. It typically increments a
counter.
for Loop

Declare i

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

Execute initializer
i is now 0

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

(i < 2) is true
since i is 0

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}

Print Welcome to Java


for Loop
Execute adjustment
statement
i now is 1

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

(i < 2) is still true


since i is 1

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}

Print Welcome to Java


for Loop
Execute adjustment
statement
i now is 2

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

(i < 2) is false
since i is 2

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}
for Loop

int i;
for (i = 0; i < 2; i++) {
System.out.println("Welcome to Java!");
}

Exit the loop. Execute the next


statement after the loop
CAUTION!
• The initial-action in a for loop is a list of zero or
more comma-separated expressions
• The action-after-each-iteration in a for loop is a
list of zero or more comma-separated statements
• Therefore, the following two for loops are
correct. They are rarely used in practice,
however.
for (int i = 1; i < 100; System.out.println(i++));

for (int i = 0, j = 0; (i + j < 10); i++, j++) {


// Do something

}
CAUTION!
• If the loop-continuation-condition in a for loop is
omitted, it is implicitly true.
CAUTION!
• Do NOT add a semicolon at the end of the for
clause:
Don’t do
this!

for (int i=0; i<10; i++);


{
System.out.println("i is " + i);
}

• (here ; is executed as for loop statement,


therefore we won’t see any output)
Program
• Write a program that sums a series that starts
with 0.01 and ends with 1.0. The numbers in the
series will increment by 0.01, as follows: 0.01 +
0.02 + 0.03 and so on.

TestSum
Program
• Write a program that uses nested for loops to
print a multiplication table.

MultiplicationTable
Which Loop?
• All loops are equal
Which Loop?
• Some recommendations
1. Use the most intuitive loop
2. If number of repetitions known for
3. If number of repetitions unknown while
4. If should be executed at least once (before testing
the condition) do-while
Break/continue
break
• break causes the loop to be abandoned, and
execution continues following the closing curly
brace.

while ( i > 0 )
{
....
if ( j == .... )
break; // abandon the loop
….
}
// end of the loop body
break will bring
you here
continue
• continue causes the rest of the current round of
the loop to be skipped.
• "while" or "do" loop moves directly to the next
condition test of the loop.
• "for" loop moves to the
“action-after-each-iteration” expression, and then to
the condition test.
Continue/break

• continue causes the rest of the current round of


the loop to be skipped.
• Break causes the loop to be skipped overall.
• Those two keywords might be useful sometimes
• But they make programs more difficult to read
• So use them rarely
• Use a boolean flag instead
Program
• Examples for using the break and continue
keywords:

● TestBreak.java

TestBreak

● TestContinue.java

TestContinue
Program
• Here is a program for guessing a number. You
can rewrite it using a break statement.

GuessNumberUsingBreak
Program
• Write a program that displays the first 50 prime
numbers in five lines, each of which contains 10
numbers. An integer greater than 1 is prime if its
only positive divisor is 1 or itself. For example, 2, 3,
5, and 7 are prime numbers, but 4, 6, 8, and 9 are
not.

PrimeNumber Run
Lecture-11
By
Dr. Bharati Mishra
Methods
Motivation
• Suppose we want to write a program to find the
sum of integers
• from 1 to 10
• from 20 to 30
• from 35 to 45
Naïve Solution
• Obvious solution

int sum = 0;
for (int i = 1; i <= 10; i++)
sum += i;
System.out.println("Sum from 1 to 10 is " + sum);

sum = 0;
for (int i = 20; i <= 30; i++)
sum += i;
System.out.println("Sum from 20 to 30 is " + sum);

sum = 0;
for (int i = 35; i <= 45; i++)
sum += i;
System.out.println("Sum from 35 to 45 is " + sum);
Refactor
• What about some refactoring?

int sum = 0;
for (int i = 1x ; i <= 10;
y i++)
sum += i;
x to 10
System.out.println("Sum from 1 y is " + sum);

sum = 0;
x
for (int i = 20; y
i <= 30; i++)
sum += i;
x to 30
System.out.println("Sum from 20 y is " + sum);

sum = 0;
x
for (int i = 35; y
i <= 45; i++)
sum += i;
y is " + sum);
x to 45
System.out.println("Sum from 35
Solution
• A better approach is to use a method
name
modifier output input

public static int sum(int x, int y)


{
int sum = 0;
Method for (int i = x; i <= y; i++)
body
sum += i;
return sum;
}
Invoking a Method

• First, a method should be defined


• Then we can use the method
• i.e. calling or invoking a method

public static void main(String[] args) {


int total1 = sum(1, 10);
int total2= sum(20, 30);
int total3 = sum(35, 45);
int total4 = sum(35,1000);
}
Invoking a Method

• When calling a method within the same class, we


directly call the method

public class TestClass{


public static void main(String[] args) {
int total1 = sum(1, 10);
} calling
//---------------------------------------------- directly
public static int sum(int x, int y)
{
int sum = 0;
for (int i = x; i <= y; i++)
sum += i;
return sum;
}
}
Invoking a Method

• When calling a method from another class, use


class name if a static method
public class AnotherClass{
public static int sum(int x, int y)
{
int sum = 0;
for (int i = x; i <= y; i++)
sum += i;
return sum;
}
}

public class TestClass{


public static void main(String[] args) {
int total1 = AnotherClass .sum(1, 10);
} Class
} name
Invoking a Method

• When calling a method from another class, use


class name if a static method
public class AnotherClass{
public int sum(int x, int y)
{
int sum = 0;
for (int i = x; i <= y; i++)
sum += i;
return sum;
}
}
public class TestClass{
public static void main(String[] args) {
AnotherClass a = new AnotherClass();
int total1 = a.sum(1, 10);
} Instance
} name
So…

• Method is
• A collection of statements grouped together to
perform an operation
• To use a method
• We invoke the method
• E.g. int result = sum(1,10);
Method Signature

• Method signature
• Combination of the method name and the parameter
list
Method header

signature

public static int sum(int x, int y)


{
int sum = 0;
for (int i = x; i <= y; i++)
sum += i;
return sum;
}
Parameters

Formal parameter
• Parameters
public static int sum(int x, int y)
{
int sum = 0;
for (int i = x; i <= y; i++)
sum += i;
return sum;
}
public static void main(String[] args)
{
int total1 = sum(1, 10);
} Actual parameter
Parameters

• Formal parameters:
• Variables defined in the method header
• Actual parameters:
• When a method is invoked, you pass a value to
the parameter. This value is referred to as
actual parameter or argument.
Output

• If the method does not return a value, the “return


type” is the keyword void.
• It means “nothing” will be returned
• A method may return a value:
• Use return keyword to return the value…
• E.g. return sum;
• “return” keyword is required if return type is anything
other than void
Tip

• A return statement is not required for a void


method.
• return still can be used for terminating the method
• This is not often done
Programming Style

• Use “return” only once in a method!


• Easier to debug and trace
public int max(int x, int y)
{
public int max(int x, int y) int result= 0;
{
if (x > y) if(x > y)
return x; result = x;
else else
return y; result = y;
}
return result;
Two exit points
}
One exit point:
This is better
Program
• This program demonstrates calling a method max
to return the largest value among a set of values.

TestMax
Program
• Passing arguments

public static void main(String[] args) public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

i is now 5

public static void main(String[] args) public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

j is now 2

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

invoke method max(i,j)

public static void main(String[] args) public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

pass the value of i to x


pass the value of j to y

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

Declare variable result

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

(x > y) is true because (5 > 2)

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

result is now 5

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

return result which is 5

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

return max(i, j) and assign the


return value to k

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Program Trace

finished

public static void main(String[] args) Public static int max(int x, int y)
{ {
int i = 5; int result= 0;
int j = 2;
int k = max(i, j); if(x > y)
} result = x;
else
result = y;

return result;
}
Modularizing Code

• Methods reduce redundant coding and enable


code reuse.
• Methods modularize code and improve the quality
of the program.

PrimeNumberMethod
Program

• Write a method that converts a decimal integer to


a hexadecimal. Write another method to convert
decimal to hexadecimal.

Decimal2HexConversion
Program Explained

• Converting a decimal number x (e.g. 74) into a


hexadecimal number (e.g. 4A)
1. Divide x by 16
2. Save remainder and quotient
3. Repeat step 1 and 2 until quotient is 0
4. Form the hexadecimal number from remainders (the
most recent remainder will be the leftmost digit)
Memory & Methods
Stack
• A data structure
• Last in, first out (LIFO)
• Two basic operation
• Pop
• Push
Push Pop

Z
Y
x
Memory
• How memory is arranged
1. Registers
• Inside the processor, very limited, you have no direct access
2. RAM
• Stack memory
• Inside RAM, very fast, lifetime of objects should be known, all
primitive variables placed here
• Heap memory
• Inside RAM, reference values placed here
3. Constant values
• Will be directly replaced in code
Revisiting Program

• Each time a method is called, the system stores


parameters and variables in stack memory.

Public static int max(int x, int y) public static void main(String[] args)
{ {
int result= 0; int i = 5;
int j = 2;
if(x > y) int k = max(i, j);
result = x; }
else
result = y;

return result;
}
Memory
• How memory is managed?

Space
Space required for
required for max
max method:
method: Result: 5
x:5 x:5
y:2 y:2

Space Space Space Space Stack


required for required for required for required for is empty
main method: main method: main method: main method:
k: k: k: k: 5
i:5 i:5 i:5 i:5
j:2 j:2 j:2 j:2
Pass by Reference

• What about reference types?


• E.g. Random r = new Random();

Actual Object


Space
required for
main
method:
r
(reference)
Heap Memory
Stack Memory
Pass by Reference

• What about reference types?


• E.g. Random r = new Random();

Space
required for
test
method: Actual Object
x

Space
required for
main
method:
r
(reference)
Heap Memory
Stack Memory
Passing Arguments

• If primitive types are passed


• Value is passed
• Changes inside method will not affect the variable
outside the method
• If a reference type is passed
• Reference is passed (address of memory location
containing actual object)
• Changes inside the method will affect the variable
Method Overload
Method Overload

• Different versions of the same method accepting


different arguments

TestMethodOverloading
Tip

• Method overload is only based on input


arguments
• Method overload can not be based on different
output values
• Method overload cannot be based on different
modifiers
Method Overload

• Sometimes there may be two or more possible


matches for an invocation of a method, but the
compiler cannot determine the most specific
match.
• This is referred to as ambiguous invocation.
Ambiguous invocation is a compilation error.
Ambiguous invocation
public class AmbiguousOverloading {
public static void main(String[] args) {
System.out.println(max(1, 2));
}

public static double max(int num1, double num2) {


double result = 0;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}

public static double max(double num1, int num2) {


double result = 0;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
}
Variable Scope
Variable Scope

• Scope:
• Part of the program where the variable can be
referenced.
• A local variable:
• A variable defined inside a method.
• The scope of a local variable starts from its
declaration and continues to the end of the block
that contains the variable.
Variable Scope

• A variable declared in the initial action part of a


for loop has its scope in the entire loop.
• A variable declared inside a for loop body has its
scope limited in the loop body from its
declaration and to the end of the block.
Variable Scope

• You can declare a local variable with the same


name multiple times in different non-nesting
blocks in a method
• You cannot declare a local variable twice in
nested blocks.
Variable Scope

• A variable declared in a method


Method Abstraction
Abstraction

• You can think of the method body as a black box


that contains the detailed implementation for
the method.
Method Benefits

• Write a method once and reuse it anywhere.


• Hide the implementation from the user.
• Change it without affecting the user
• Reduce complexity.
Method Benefits

• Example
• Math class provides many methods
• Trigonometric Methods
• Exponent Methods
• Rounding Methods
• min, max, abs, and random Methods
Stepwise Refinement

• When writing a large program, you can use the


“divide and conquer” strategy, also known as
stepwise refinement, to decompose it into
sub-problems.
• The sub-problems can be further decomposed
into smaller, more manageable problems.
Task 1-1
Task 1
Task 1-2
Main Task Task 2

Task 3
Stepwise Refinement

• An example to demonstrate the stepwise


refinement approach:

PrintCalendar
Stepwise Refinement
Stepwise Refinement
Stepwise Refinement
Stepwise Refinement
Stepwise Refinement
Stepwise Refinement
Top Down Design

• Top-down approach is to implement one method


in the structure chart at a time from the “top to
the bottom”.
• Implement the main method first and then use a
stub for each one of the methods.
• Stubs can be used for the methods waiting to be
implemented.
• A stub is a simple but incomplete version of a
method.
• The use of stubs enables you to test invoking the
method from a caller.

A Skeleton for printCalendar


Bottom Up Design

• Bottom-up approach is to implement one method


in the structure chart at a time from the “bottom
to the top”.
• For each method implemented, write a test
program to test it.
Comparison

• Both top-down and bottom-up methods are fine.


• Both approaches implement the methods
incrementally and help to isolate programming
errors and makes debugging easy.
• Sometimes, they can be used together.
Program Revisited

• An example to demonstrate the stepwise


refinement approach:

PrintCalendar
Program

• As introduced before, each character has a


unique Unicode between 0 and FFFF in
hexadecimal (65535 in decimal). To generate a
random character is to generate a random
integer between 0 and 65535. The Unicode for
lowercase letters are consecutive integers
starting from the Unicode for 'a', then for 'b', 'c',
..., and 'z'. A random character between any two
characters ch1 and ch2 with ch1 < ch2 can be
generated as follows:

Random r = new Random();


char x = ch1 + r.nextInt(ch2 – ch1 + 1)
Program

• Random character generator

RandomCharacter TestRandomCharacter
Lecture-12
By
Dr. Bharati Mishra
Arrays
Motivation
• Read one hundred numbers, compute their
average, and find out how many numbers are
above the average.
• Declaring 100 integer variables?
Solution
• Better solution: using arrays
• Array is a data structure that represents a
collection of the same type of data.

int[] myList = new int[7];


23
45
53
16
32
8
91
Solution
• Array is a reference type

int[] myList = new int[7];

23
0x675
45
myList 53
(memory location of the
actual array) 16
32
8
Array element
at index 6 91 Value of
element at
index 6
Declaring Array
• First approach:

datatype[] arrayRefVar;
Example:

double[] myList;
• Second approach (possible, but not preferred):

Example:
datatype arrayRefVar[];

double myList[];
Creating Array

arrayRefVar = new datatype[arraySize];

•Example:
//two steps
double[] myList;
myList = new double[10];

//one step
double[] myList= new double[10];
Length of Array
• Once an array is created, its size is fixed.
• i.e. it cannot be changed!
• You can find the size of an array using

arrayRefVar.length
• For example

int length = myList.length;


• This returns 7.
Initial Values
• When an array is created, its elements
are assigned the default value of
• 0 for the numeric primitive data types
• '\u0000' for char
• false for boolean
Indexed Variables

• The array elements are accessed


through an index.
• The array indices are 0-based,
• i.e., myList indices starts from 0 to 6.
Indexed Variables

• Each element of array is an indexed


variable:
arrayRefVar[index]
;
• Example (accessing first element)

myList[0];
Populate Array

• Individual initialization

double[] myList = new double[4];


myList[0] = 1.9;
myList[1] = 2.9;
myList[2] = 3.4;
myList[3] = 3.5;
Populate Array

• Shorthand initialization

double[] myList = {1.9, 2.9, 3.4, 3.5};

• This shorthand syntax must be in one


statement.
• Splitting it would cause a syntax error!
Indexed Variables

• First create an array


• Populate the array
• Use indexed variables to access items
in the same way as a regular variable.

myList[2]= myList[0] + myList[1];


Program
• Read one hundred numbers, compute their
average, and find out how many numbers are
above the average.

AnalyzeNumbers
Program Trace

Declare array variable

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
Values
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}
Program Trace

Declare array variable, and create


an array.

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i is 1

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i is less than 5

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After this line is executed, value[1]


is 1

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i is 2 now

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i (=2) is less than 5

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After this line is executed, value[2]


is 3

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After i++, i becomes 3

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i (=3) is less than 5

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After this line, values[3] becomes 6


(3 + 3)

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After this, i becomes 4

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i (=4) is still less than 5

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After this, values[4] becomes 10 (4 +


6)

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After i++, i becomes 5

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

i ( =5) < 5 is false. Exit the loop

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

After this line, values[0] is 11 (1 +


10)

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Program Trace

Finished

public class Test {


public static void main(String[] args) {
int[] values = new int[5];
for (int i = 1; i < 5; i++) {
values[i] = i + values[i-1];
}
values[0] = values[1] + values[4];
}
}

Values
Example
• Initializing arrays with input values

Scanner input = new Scanner(System.in);

for (int i = 0; i < myList.length; i++)


myList[i] = input.nextDouble();
Example
• Initializing arrays with random values

for (int i = 0; i < myList.length; i++)


{
myList[i] = Math.random() * 100;
}
Example
• Printing arrays

for (int i = 0; i < myList.length; i++)


System.out.print(myList[i] + " ");
Example
• Summing all elements

double total = 0;
for (int i = 0; i < myList.length; i++)
total += myList[i];
Example
• Finding the largest element

double max = myList[0];

for (int i = 1; i < myList.length; i++) {


if (myList[i] > max)
max = myList[i];
}
Example
• Random shuffling
for (int i = 0; i < myList.length; i++)
{
// Generate an index randomly
int index = (int)(Math.random()
* myList.length);

// Swap myList[i] with myList[index]


double temp = myList[i];
myList[i] = myList[index];
myList[index] = temp;
}
Example
• Shifting Elements
double temp = myList[0]; // Retain the first element

// Shift elements left


for (int i = 1; i < myList.length; i++) {
myList[i - 1] = myList[i];
}

// Move the first element to fill in the last position


myList[myList.length - 1] = temp;

myList
for-each Loops
for-each
• JDK 1.5 introduced a new for loop that enables
you to traverse the complete array sequentially
without using an index variable.

for (elementType value:arrayRefVar)


• For example, the following code displays all


elements in the array myList:

for (double value: myList)


System.out.println(value);
Program
• The problem is to write a program that picks four
cards randomly from a deck of 52 cards. All the
cards can be represented using an array named
deck, filled with initial values 0 to 51 as follows:

int[] deck = new int[52];


// Initialize cards
for (int i = 0; i < deck.length; i++)
deck[i] = i;

DeckOfCards Run
Program
• Cards 0-12: 13 Spades
• Cards 13-25: 13 Hearts
• Cards 26-38: 13 Diamonds
• Cards 39-51: 13 Clubs

• Suit:
• 0-3 (i.e. Spades, Hearts, Diamonds, Clubs)
• Rank:
• 0-12 (i.e. Ace, 2, …, 10, Jack, Queen, King)

• deck / 13: suit of the card (0-3)


• deck % 13: rank of the card (0-12)
Program
Array Copy
Array Copy
• Arrays are reference type, so be careful!
list2 = list1;
• After assignment, both lists will point to the
same memory location.
Array Copy
• To copy the contents (and not the reference),
you can use a loop:

int[] sourceArray = {2, 3, 1, 5, 10};


int[] targetArray = new int[sourceArray.length];

for (int i = 0; i < sourceArrays.length; i++)


targetArray[i] = sourceArray[i];
Array Copy
• To copy the contents (and not the reference),
you can also use the arrayCopy utility:

System.arraycopy(source, srcPos, target, tarPos, length);

• Example

int[] sourceArray = {2, 3, 1, 5, 10};


int[] targetArray = new int[sourceArray.length];

System.arraycopy(sourceArray, 0, targetArray,
0,sourceArray.length);
Passing Array
Passing Array
• Two ways to pass an array to a method

public static void printArray(int[] array) {


for (int i = 0; i < array.length; i++)
System.out.print(array[i] + " ");
}

int[] list = {3, 1, 2, 6, 4, 2};


printArray(list);

printArray(new int[]{3, 1, 2, 6, 4, 2});

Anonymous Array
Passing Values
• Two Java uses pass by value to pass arguments
to a method.
• There are important differences between passing
a value of variables of primitive data types and
passing arrays.

int x = 10; int[] y = new int[7];

23
10
45
x y 53
16
32
8
Passing Values
• For a parameter of a primitive type value:
• The actual value is passed.
• Changing the value inside the method does not
affect the value outside the method.
• For a parameter of an array (reference) type:
• The value of the parameter contains a reference
to an array
• Any changes to the array that occur inside the
method body will affect the original array that
was passed as the argument.
Program

•Objective: Demonstrate differences of


passing primitive data type variables and
array variables.

TestPassArray Run
Return Array
public static int[] reverse(int[] list)
{
int[] result = new int[list.length];

for (int i = 0, j = result.length - 1;


i < list.length; i++, j--)
{
result[j] = list[i];
}

return result;
}

int[] list1 = new int[]{1, 2, 3, 4, 5, 6};


int[] list2 = reverse(list1);

list 1 2 3 4 5 6

result 6 5 4 3 2 1
Program

•Generate 100 lowercase letters


randomly and assign to an array of
characters. Count the occurrence of
each letter in the array.

CountLettersInArray Run
Variable-Length Argument Lists
Variable Length args

•You can pass a variable number of


arguments to a method

Typename … parameterName

•Type should be followed by an ellipsis


(…)
Variable Length args

•Only one variable-length argument in


each method
•Must be the last parameter
Variable Length args

•Java treats it like an array


•You can use
• An array or
• The variable-length argument list
Variable Length args

•Problem: finding the maximum in a list


of unspecified number of values

VargArgsDemo Run
Searching & Sorting
Search

• The process of looking for a specific


element in a list
• A common task in computer
programming
• We will learn about two commonly
used approaches
• Linear search
• Binary search
Search

• Example
public class LinearSearch {
/** The method for finding a key in the list */
public static int linearSearch(int[] list, int key)
{
int result = -1;

for (int i = 0; i < list.length; i++)


if (key == list[i])
result = i;

return result;
}
}
Linear Search
• The linear search approach compares
the key element, sequentially with each
element in the array list.
• The method continues to do so until the
key matches an element in the list or the
list is exhausted without a match being
found.
• If a match is made, the linear search
returns the index of the element in the
array that matches the key.
• If no match is found, the search returns
-1.
Linear Search

• Illustration of linear search


Key List

3 6 4 1 9 7 3 2 8

3 6 4 1 9 7 3 2 8

3 6 4 1 9 7 3 2 8

3 6 4 1 9 7 3 2 8

3 6 4 1 9 7 3 2 8

3 6 4 1 9 7 3 2 8
Binary Search

• For binary search to work, the


elements in the array must already
be ordered.
• e.g. 2 4 7 10 11 45 50 59 60 66 69
Binary Search
1. Compare the key with the element in
the middle of the array
2. If the key is less than the middle
element, you only need to search the
key in the “first half” of the array.
3. If the key is equal to the middle
element, the search ends with a match.
4. If the key is greater than the middle
element, you only need to search the
key in the “second half” of the array.
Binary Search

• Example

Key List

8 1 2 3 4 6 7 8 9

8 1 2 3 4 6 7 8 9

8 1 2 3 4 6 7 8 9
Binary Search
/** Use binary search to find the key in the list */
public static int binarySearch(int[] list, int key)
{
int low = 0;
int high = list.length - 1;
int result = -1;

while (high >= low) {


int mid = (low + high) / 2;
if (key < list[mid])
high = mid - 1;
else if (key == list[mid])
result = mid;
else
low = mid + 1;
}

if(result == -1)
result = -1 – low;

return result;
}
Binary Search

• Java provides several overloaded


binarySearch methods
• (Arrays should be ordered)

int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 79};
int index = java.util.Arrays.binarySearch(list, 11));

char[] chars = {'a', 'c', 'g', 'x', 'y', 'z'};


int index =java.util.Arrays.binarySearch(chars, 't'));
Sorting

• We will look at two different types


of sorting
• Selection sort
• Insertion sort
Selection Sort
1. Find the largest (smallest) number in
the list and place it last (first).
2. Then find the largest (smallest)
number remaining and place it next
to last (first)
3. Repeat step 2 until the list contains
only a single number
Selection Sort
Selection Sort
• Program design

for (int i = 0; i < list.length; i++)


{
//select the smallest element in list[i..list.length-1];
//swap the smallest with list[i], if necessary;
}
Selection Sort
• //find the smallest element in the
unsorted portion of the list

double currentMin = list[i];


int currentMinIndex = i;
for (int j = i; j < list.length; j++)
{
if (currentMin > list[j])
{
currentMin = list[j];
currentMinIndex = j;
}
}
Selection Sort

• // if list[i] is in its correct position

if (currentMinIndex != i)
{
list[currentMinIndex] = list[i];
list[i] = currentMin;
}
Selection Sort
/** The method for sorting the numbers */
public static void selectionSort(double[] list) {
for (int i = 0; i < list.length; i++) {
// Find the minimum in the list[i..list.length-1]
double currentMin = list[i];
int currentMinIndex = i;
for (int j = i + 1; j < list.length; j++) {
if (currentMin > list[j]) {
currentMin = list[j];
currentMinIndex = j;
}
}
// Swap list[i] with list[currentMinIndex] if necessary;
if (currentMinIndex != i) {
list[currentMinIndex] = list[i];
list[i] = currentMin;
}
}
}

selectionSort
Insertion Sort
• The insertion sort algorithm sorts a list of
values by repeatedly inserting an
unsorted element into a sorted sublist
until the whole list is sorted.
Insertion Sort
int[] myList = {2, 9, 5, 4, 8, 1, 6};
Insertion Sort
• Example:
int[] myList = {2, 9, 5, 4, 8, 1, 6};

2 9 5 4 8 1 6
2 9 5 4 8 1 6
2 5 9 4 8 1 6
2 4 5 9 8 1 6
2 4 5 8 9 1 6
1 2 4 5 8 9 6
1 2 4 5 6 8 9
InsertSort
Insertion Sort
public static void insertionSort(double[] list)
{
for (int i = 1; i < list.length; i++)
{
/** insert list[i] into a sorted sublist list[0..i-1] so that
list[0..i] is sorted. */
double currentElement = list[i];
int k;
for (k = i - 1; k >= 0 && list[k] > currentElement; k--)
{
list[k + 1] = list[k];
}

// Insert the current element into list[k+1]


list[k + 1] = currentElement;
}
} InsertSort
Sort Utility
• Since sorting is frequently used in
programming, Java provides several
overloaded sort methods for sorting.

double[] numbers = {6.0, 4.4, 1.9, 2.9, 3.4, 3.5};


java.util.Arrays.sort(numbers);

char[] chars = {'a', 'A', '4', 'F', 'D', 'P'};


java.util.Arrays.sort(chars);
Lecture-15
By
Dr. Bharati Mishra
Class
Motivation
• Suppose you want to develop a graphical user
interface as shown below. How do you program it?
Object
• object
• An entity in the real world that can be distinctly
identified.
• A student, a desk, a circle, a button, and even a loan
can all be viewed as objects.
• has a unique identity, state, and behaviors.
• State = a set of data fields (also known as
properties) with their current values.
• Behavior = a set of methods
Class vs. Object
• Classes are constructs that define objects of the
same type
Class Example
UML
UML Notation
• UML class diagram
Constructor
Constructor
• Constructors are a special kind of methods that
are invoked to construct objects.

Circle() Constructor
{ with no
} argument

Circle(double newRadius)
Constructor
{
with argument
radius = newRadius;
}
Constructor
• Constructors must have the same name as the
class itself.
• Constructors do not have a return type—not even
void.
• Constructors are invoked using the new operator
when an object is created.
• Constructors play the role of initializing objects.
Constructor
• Creating objects using constructors

new ClassName();

new Circle();

new Circle(5.0);
Constructor
• A class may be declared without constructors.
• In this case, a no-arg constructor with an empty
body is implicitly declared in the class.
• This constructor, called a default constructor, is
provided automatically only if no constructors are
explicitly declared in the class.
Creating Objects

• Declaring & creating objects in a single step

Circle myCircle = new Circle();

declare create

• Two steps

//step 1: declare
Circle myCircle;
//step 2: create
myCircle = new Circle();
Accessing Data Fields & Methods
Access

• Referencing the object’s data fields:

myCircle.radius

• Invoking the object’s method:

myCircle.getArea()
Data Fields

• The data fields can be of reference types


• Example: name data field is of type String

public class Student {


String name; // name has default value null
int age; // age has default value 0
boolean isScienceMajor; // has default value false
char gender; // c has default value '\u0000‘

//methods …
}
null

• If a data field of a reference type does not


reference any object, the data field holds a
special literal value: null.
Default Values

• The default value of a data field is


• null for a reference type
• 0 for a numeric type
• false for a boolean type
• '\u0000' for a char type
• However, Java assigns no default value to a local
variable inside a method.
Default Values

• Java assigns no default value to a local variable


inside a method.

public class Test {


public static void main(String[] args) {
int x; // x has no default value
String y; // y has no default value
System.out.println("x is " + x);
System.out.println("y is " + y);
}
}

Compilation error: variables


not initialized
Program
• Accessing methods and data fields

TestCircle1 Run

TV

TestTV Run
Copying

• Primitive type copy


Copying

• Reference type copy


Garbage Collector

• As shown in the previous figure, after the


assignment statement c1 = c2, c1 points to the
same object referenced by c2.
• The object previously referenced by c1 is no
longer referenced.
• This object is known as garbage.
• Garbage is automatically collected by JVM.
Garbage Collector

• TIP: If you know that an object is no longer


needed, you can explicitly assign null to a
reference variable for the object.
• The JVM will automatically collect the space if
the object is not referenced by any variable.
Instance Fields

• Instance fields belong to a specific instance.


• Instance methods are invoked by an instance of
the class.
• i.e. non-static methods
Static

• Static methods are not tied to a specific object.


• Static variables are shared by all the instances of
the class.
• Static constants are final variables shared by all
the instances of the class.
• All declared using static keyword
Static vs. Instance

• Example
Static vs. Instance

• Static fields or methods can be used from instance


or static methods.
• Instance fields or methods can be only used from
instance methods.
• So: a variable or method that does not depend on
a specific instance of the class, should be specified
as static.
Static vs. Instance
public class Foo {
int i = 5;
static int k = 2;

public static void main(String[] args) {


int j= i; // Wrong because i is an instance variable
m1(); // Wrong because m1() is an instance method
}

public void m1() {


i = i + k + m2(i, k);
// Correct: since instance and static variables and
//methods can be used in an instance method
}
public static int m2(int i, int j) {
return (int)(Math.pow(i, j));
}
}
Static vs. Instance
public class Foo {
int i = 5;
static int k = 2;

public static void main(String[] args) {


Foo foo = new Foo();
int j= foo.i; // OK
foo.m1(); // OK
}

public void m1() {


i = i + k + m2(i, k);
}
public static int m2(int i, int j) {
return (int)(Math.pow(i, j));
}
}
Static vs. Instance

• Which one is a better design?


Program

• This example adds a class (i.e. static) variable


numberOfObjects to track the number of Circle
objects created.

Circle2

TestCircle2 Run
Accessibility

1. Package access (default in Java)


• The class, variable, or method can be accessed by
any class in the same package.

2. public
• The class, data, or method is visible to any class in
any package.

3. private
• The data or methods can be accessed only by the
declaring class.
Accessibility Example

• Access C1 methods & fields from C2/C3?

Package 1 Package 2
public class C2 {
public class C1 { public class C3 {
void aMethod() {
public int x; void aMethod() {
C1 o = new C1();
int y; C1 o = new C1();
}
private int z; }
}
}
public void m1() {..}
void m2() {..}
private void m3() {..}
}
Accessibility Example

Package 1 Package 2
public class C2 {
public class C1 { public class C3 {
void aMethod() {
public int x; void aMethod() {
C1 o = new C1();
int y; C1 o = new C1();
//can access o.x;
private int z; //can access o.x;
//can access o.y;
//cannot access
//cannot access
public void m1() {..} //o.y;
//o.z;
void m2() {..} //cannot access
//can invoke
private void m3() {..} //o.z;
//o.m1();
} //can invoke
//can invoke o.m2()
//o.m1();
//cannot invoke
//cannot invoke
//o.m3();
//o.m2();
}
//cannot invoke
}
//o.m3();
}
}
Accessibility Example

• Which classes can access C1?

Package 1 Package 2
public class C2 {
class C1 { public class C3 {
//can access C1?
… //can access C1?
}
} //can access C2?
}
Accessibility Example

• Which classes can access C1?

Package 1 Package 2
public class C2 {
class C1 { public class C3 {
//can access C1
… //cannot access C1
}
} //can access C2
}
Accessibility Summary

• The private modifier restricts access to within a


class
• The default modifier restricts access to within a
package
• The public modifier enables unrestricted access.
Accessibility

• Example:
public class Foo {

private boolean x;

public void test()


{
System.out.println(x);
System.out.println(convert()); OK
}

private int convert(boolean b)


{
return x ? 1 : -1;
}
}
Accessibility

• Example:

public class Test {


public static void main(String[] args)
{
Foo foo = new Foo();
System.out.println(foo.x);
Error!
System.out.println(foo.convert(foo.x));
}
}

• Because x and convert are private members


Why Private?

• To protect data.

• To make class easy to maintain.


get/set

• The get and set methods are used to read and


modify private properties.
• Data encapsulation

The - sign
indicates
private
modifier
Program

• Data encapsulation

Circle3
Run

TestCircle3
Program

• Passing by value for primitive type value (the value


is passed to the parameter)
• Passing by value for reference type value (the
value is the reference to the object)

TestPassObject Run
Array of Objects
Array of Objects

• An array of objects is actually an array of reference


variables.
• So invoking circleArray[1].getArea() involves two
levels of referencing.
• circleArray references to the entire array.
• circleArray[1] references to a Circle object.

Circle[] circleArray = new Circle[10];


Array of Objects

Circle[] circleArray = new Circle[10];


Program

• Summarizing the areas of the circles

TotalArea 49
Run
Lecture-16
By
Dr. Bharati Mishra
Objectives
• Chapter 10
• Immutable objects
• this keyword
• Composition
• Differences between procedural programming &
OOP
• Guidelines for OOP
More on Objects
Immutable
• Immutable object:
• If the contents of an object cannot be changed
once the object is created
• Its class is called an immutable class.

Circle3
Immutable
•A class with all private data fields and
without mutators is not necessarily
immutable.
• Example: next slide (Student class)
Example..

public class BirthDate {


private int year;
private int month;
private int day;

public BirthDate(int newYear,int newMonth,int


newDay) {
year = newYear;
month = newMonth;
day = newDay;
}

public void setYear(int newYear) {


year = newYear;
}
}
Example
public class Student {
private int id;
private BirthDate birthDate;

public Student(int ssn,int year, int month, int day)


{
id = ssn;
birthDate = new BirthDate(year, month, day);
}

public int getId() {


return id;
}

public BirthDate getBirthDate() {


return birthDate;
}
}
Example …

public class Test {


public static void main(String[] args) {
Student student = new Student(111223333,1970, 5, 3);
BirthDate date = student.getBirthDate();
date.setYear(2010); // Now the student birth year is
// changed!
}
}

8
Immutable
•For a class to be immutable, it must
1. Mark all data fields private
2. Provide no mutator methods
3. Provide no accessor methods that would
return a reference to a mutable data field
object.
Scope
Variable Scope

•The scope of instance and static data fields


is the entire class.
• They can be declared anywhere inside a
class.
•The scope of a local variable starts from its
declaration and continues to the end of the
block that contains the variable.
• A local variable must be initialized explicitly
before it can be used.
Variable Scope

•Example
Variable Scope
• If a local variable has the same name as a
class’s variable, the local variable takes
precedence and the class’s variable with the
same name is hidden.
Variable Scope
• Example
this Keyword
this

•The this keyword is the name of a reference


that refers to an object itself.
•One common use of the this keyword is
reference a class’s hidden data fields.
•Another common use of the this keyword to
enable a constructor to invoke another
constructor of the same class.
this

•Using this to reference hidden fields


this

•Use this to call overloaded constructor


Class Relationships
Association
Aggregation
Composition
Inheritance

Association: is a general binary relationship that describes


an activity between two classes.

19
Composition & Aggregation
Composition

•An object can contain another object.


•The relationship between the two is called
composition.
Aggregation

•Composition is a special case of the


“aggregation” relationship.
•Aggregation models “has-a” relationships.
• The owner object is called an aggregating
object.
•The subject object is called an aggregated
object.
Composition

•An object may be owned by several other


aggregating objects.
• If an object is exclusively owned by an
aggregating object, the relationship
between them is referred to as
“composition”.
Example

•“a student has a name”


• A composition relationship
•“a student has an address”
• An aggregation relationship
• An address may be shared by several
students.
UML

•UML composition & aggregation notation


UML
• Each class involved in a relationship may specify
a multiplicity.
• A multiplicity could be a number or an interval
that specifies how many objects of the class are
involved in the relationship.
• The character * means an unlimited number of
objects
• The interval m..n means that the number of
objects should be between m and n, inclusive.
UML

•An aggregation relationship is usually


represented as a data field in the
aggregating class.
UML

•Aggregation may exist between objects of


the same class.
UML

•Aggregation may exist between objects of


the same class.
Class Abstraction
OOP

• Procedural programming
• Methods
• OOP
• Entities grouping related methods and data
Class Abstraction

• Class abstraction means to separate class


implementation from the use of the class.
• The user of the class does not need to
know how the class is implemented.
Class Abstraction

• Example: Loan class

Loan

TestLoanClass

Run
Class Abstraction

• Example: BMI
BMI

UseBMIClass

Run
Class Abstraction

• Example: Course
Course

TestCource
Class Abstraction

• Example: Designing Stack

Push Pop

Z
Y
x
Class Abstraction

• Example: Stack

TestStackOfIntegers Run
Class Abstraction

• Example: Designing Stack

StackOfIntegers
Class Abstraction

• Example: Guess Date

GuessDate UseGuessDateClass Run


Class Design Guidelines
Guideline

• Coherence
• A class should describe a single entity
• All the class operations should support a
coherent purpose.
• You can use a class for students, for
example, but you should not combine
students and staff in the same class,
because students and staff have different
entities.
Guideline

• A single entity with too many


responsibilities can be broken into several
classes to separate responsibilities.
Guideline

• Classes are designed for reuse. Users can


incorporate classes in many different
combinations, orders, and environments.
• Therefore, you should design a class that
imposes no restrictions on what or when
the user can do with it.
Guideline

• Design the properties to ensure that the


user can set properties in any order, with
any combination of values.
• Design methods to function independently
of their order of occurrence.
Guideline

•Provide a public no-arg constructor and


override the equals method and the toString
method defined in the Object class
whenever possible.
Guideline

•Follow standard Java programming style and


naming conventions.
•Choose informative names for classes, data
fields, and methods.
Guideline

•Always place the data declaration before


the constructor, and place constructors
before methods.
•Always provide a constructor and initialize
variables to avoid programming errors.
Guideline

•Make the fields private and accessor


methods public if they are intended for the
users of the class.
•Make the fields or method protected if they
are intended for extenders of the class
(more on extension and inheritance later).
Guideline

•You can use get methods and set methods


to provide users with access to the private
data, but only to private data you want the
user to see or to modify.
•A class should also hide methods not
intended for client use.
Guideline

•A property (data field) that is shared by all


the instances of the class should be declared
as a static property.
Wrapper Classes
Wrapper Classes
• Java provides 8 primitive data types: byte, short, int, long, float,
double, boolean, char
• One of the limitations of the primitive data types is that we
cannot create ArrayLists of primitive data types.
• However, this limitation turns out not to be very limiting after
all, because of the so-called wrapper classes:
• Byte, Short, Integer, Long, Float, Double, Boolean, Character
• These wrapper classes are part of java.lang (just like String and
Math) and there is no need to import them.

9-52
Wrapper Classes Examples
• Creating a new object:
Integer studentCount = new Integer(12);

• Changing the value stored in the object:


studentCount = new Integer(20);

• Getting a primitive data type from the object:


int count = studentCount.intValue();

9-53
Auto Boxing / UnBoxing

• You can also assign a primitive value to a wrapper class


object directly without creating an object. This is called
Autoboxing
Integer studentCount = 12;

• You can get the primitive value out of the wrapper class
object directly without calling a method (as we did
when we called .intValue()). This is called Unboxing

System.out.println(studentCount);

9-54
Wrapper Classes and ArrayList Example
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
Scanner k = new Scanner(System.in);
System.out.println("Enter some non-zero integers. Enter 0 to end.");
int number = k.nextInt();
while (number != 0)
{
list.add(number); // autoboxing happening here
number = k.nextInt();
}

System.out.println("Your numbers in reverse are:");


for (int i = list.size() - 1; i >= 0; i--) {
System.out.println(list.get(i)); // unboxing happening here
}

9-55
Examples
The Parse Methods
• One of the useful methods on the Wrapper classes is the parse
methods. These are static methods that allow you to convert a
String to a number.

• Each class has a different name for its parse method:


• The Integer class has a parseInt method that converts a String to an int

• The Short class has a parseShort method that converts a String to a Short

• The Float class has a parseFloat method that converts a String to a Float

• Etc.

9-57
The Parse Methods Examples
byte b = Byte.parseByte("8");
short sVar = Short.parseShort("17");
int num = Integer.parseInt("28");
long longVal = Long.parseLong("149");
float f = Float.parseFloat("3.14");
double price = Double.parseDouble("18.99");

• If the String cannot be converted to a number, an exception is


thrown. We will discuss exceptions later.

9-58
Helpful Methods on Wrapper Classes
• The toString is static method that can convert a number back to a
String:

int months = 12;


double PI = 3.14;
String monthsStr = Integer.toString(months);
String PIStr = Double.toString(PI);

• The Integer and Long classes have three additional methods to


do base conversions: toBinaryString, toHexString, and
toOctalString

int number = 16;


System.out.print(Integer.toBinaryString(number) + “ “ +
Integer.toHexString(number) + “ “ +
Integer.toOctalString(number));

• output: 10000 10 20
9-59
Helpful Static Variables on Wrapper
Classes
• The numeric wrapper classes each have a set of static final
variables to know the range of allowable values for the data
type:
• MIN_VALUE
• MAX_VALUE

System.out.println("The minimum val for an int is “ +


Integer.MIN_VALUE);

System.out.println("The maximum val for an int is “ +


Integer.MAX_VALUE);

9-60
The Static valueOf Methods
The numeric wrapper classes have a useful
class method, valueOf(String s). This method
creates a new object initialized to the value
represented by the specified string. For
example:

Double doubleObject = Double.valueOf("12.4");


Integer integerObject = Integer.valueOf("12");

61
61
BigInteger and BigDecimal
If you need to compute with very large integers or high
precision floating-point values, you can use the
BigInteger and BigDecimal classes in the java.math
package. Both are immutable. Both extend the Number
class and implement the Comparable interface.

62
62
BigInteger and BigDecimal
BigInteger a = new BigInteger("9223372036854775807");
BigInteger b = new BigInteger("2");
BigInteger c = a.multiply(b); // 9223372036854775807 * 2
System.out.println(c);
LargeFactorial Run

BigDecimal a = new BigDecimal(1.0);


BigDecimal b = new BigDecimal(3);
BigDecimal c = a.divide(b, 20, BigDecimal.ROUND_UP);
System.out.println(c);
63
63
Lecture-16
By
Dr. Bharati Mishra
Objectives
• Chapter 11
• Inheritance
• Subclass, superclass
• super keyword
• abstract keyword
• Overriding methods
• Polymorphism and dynamic binding
• final keyword
• ArrayList
Motivation
• Suppose you want to define classes to model
circles, rectangles, and triangles.
• These classes have many common features.
• What is the best way to design these classes so
to avoid redundancy?
• The answer is to use inheritance.
Inheritance
Superclass

GeometricObject1

Circle4

Rectangle1

TestCircleRectangle

Run
Inheritance
• Models “is-a” relationship
• Not all “is-a” relationships should be modeled
using inheritance
• For class A to extend class B, A should contain more
detailed information than B.
• Do not blindly extend a class just for the sake of
reusing methods!
Inheritance
• A subclass does not inherit the private members of
its parent class.
• A subclass is not a subset of the superclass
• Contains more information!
• Java does not support multiple inheritance
• It can be achieved through interfaces (an advanced
topic)
abstract
• An abstract class may or may not include abstract
methods.
• Abstract classes cannot be instantiated, but they
can be sub-classed.
• An abstract method is a method that is declared
without an implementation.
• If a class includes abstract methods, the class
itself must be declared abstract
abstract
• An abstract class example

public abstract class GraphicObject


{
// declare fields
// declare non-abstract methods
abstract void draw();
}
Inheritance & Constructor
Constructors
• Are superclass constructors inherited?
• No. Unlike properties and methods, a superclass's
constructors are not inherited in the subclass.
Constructors
1. The constructors are invoked either explicitly:
• Using the super keyword
2. Or implicitly:
• If the keyword super is not explicitly used, the
superclass's no-arg constructor is automatically
invoked.
Constructors
• A constructor may invoke
• An overloaded constructor or
• Its superclass’s constructor
• If none of them is invoked explicitly, the compiler
puts super() as the first statement in the
constructor.
Constructors
• Example
super
• The keyword super refers to the superclass of
the class in which super appears.
• This keyword can be used in two ways:
• To call a superclass constructor
• To call a superclass method
Constructors
• You must use the keyword super to call the
superclass constructor.
• Invoking a superclass constructor’s name in a
subclass causes a syntax error.
• Java requires that the statement that uses the
keyword super appear first in the constructor.
Chaining
• Constructor chaining
• Constructing an instance of a class invokes all the
superclasses’ constructors along the inheritance chain.
• This is called constructor chaining.
Chaining
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty(); 1. Start from the
} main method
public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty(); 2. Invoke Faculty
}
constructor
public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}
3. Invoke Employee’s
class Employee extends Person { no-arg constructor
public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}
4. Invoke
class Employee extends Person { Employee(String)
public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}
5. Invoke Person()
constructor
class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person { 6. Execute println


public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}
7. Execute println
class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person { 8. Execute println


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty(); 9. Execute println
}

public Faculty() {
System.out.println( "(4) Faculty's no-arg constructor is invoked" );
}
}

class Employee extends Person {


public Employee() {
this("(2) Invoke Employee’s overloaded constructor" );
System.out.println( "(3) Employee's no-arg constructor is invoked" );
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println( "(1) Person's no-arg constructor invoked" );
}
}
Chaining
• Chaining in the program:
Chaining
• Find out the errors in the program:
Subclass/Superclass
Subclass
• A subclass extends properties and methods
from the superclass.
• You can also:
• Add new properties
• Add new methods
• Override the methods of the superclass
Subclass
•You could rewrite the printCircle() method
in the Circle class as follows:
Overriding
Overriding
•A subclass inherits methods from a
superclass.
•Sometimes it is necessary for the subclass to
modify the implementation of a method
defined in the superclass.
•This is referred to as method overriding.
Overriding
•Method overriding
Overriding
•An instance method can be overridden only
if it is accessible.
• Thus a private method cannot be
overridden.
•If a method defined in a subclass is private
in its superclass, the two methods are
completely unrelated.
Overriding
•Like an instance method, a static method
can be inherited.
•However, a static method cannot be
overridden.
• If a static method defined in the superclass
is redefined in a subclass, the method
defined in the superclass is hidden.
Overriding
•Overriding vs. overloading
Object Class
Object Class
•Every class in Java is descended from the
java.lang.Object class.
•If no inheritance is specified when a class is
defined, the superclass of the class is
Object.
Object Class
•Equivalent
Object Class
• The toString() method returns a string
representation of the object.
• The default implementation returns a
string consisting of:
• a class name of which the object is an
instance,
• (@),
• and a number representing this object.
Object Class

• The code displays something like


Loan@15037e5.
• This message is not very helpful or
informative.
• Usually you should override the toString
method so that it returns a digestible
string representation of the object.
Polymorphism
Polymorphism
• An object of a subtype can be used
wherever its supertype value is required.
• This feature is known as polymorphism.
Polymorphism
• Three pillars of OOP
1. Encapsulation
2. Inheritance
3. Polymorphism
Code
• Polymorphism
Code
• If polymorphism is used:
• Which implementation is used will be
determined dynamically by the Java Virtual
Machine at runtime.
• This capability is known as dynamic binding.
Code
Binding
• Suppose an object o is an instance of
classes C1, C2, ..., Cn-1, and Cn, where C1 is a
subclass of C2, C2 is a subclass of C3, ..., and
Cn-1 is a subclass of Cn.
• That is, Cn is the most general class, and C1
is the most specific class.
• In Java, Cn is the Object class.
Binding
• If o invokes a method p, the JVM searches
the implementation for the method p in C1,
C2, ..., Cn-1 and Cn, in this order, until it is
found.
• Once an implementation is found, the
search stops and the first-found
implementation is invoked.
Binding
• Matching a method signature
• The compiler finds a matching method
according to parameter type, number of
parameters, and order of the parameters at
compilation time.
• Binding a method
• A method may be implemented in several
subclasses.
• The Java Virtual Machine dynamically binds
the implementation of the method at
runtime.
Generic Programming

• Polymorphism allows methods to be used


generically for a wide range of object
arguments.
• This is known as generic programming.
Binding
• If a method’s parameter type is a superclass
(e.g., Object), you may pass an object to
this method of any of the parameter’s
subclasses (e.g., Student or String).
• When an object (e.g., a Student object or a
String object) is used in the method, the
particular implementation of the method of
the object that is invoked (e.g., toString) is
determined dynamically.
Casting
Casting
• Casting can be used to convert an object of
one class type to another within an
inheritance hierarchy.
Casting
• The following statement causes a compilation
error:

• Because a Student object is always an


instance of Object, but an Object is not
necessarily an instance of Student!
Casting
• Explicit casting must be used when casting
an object from a superclass to a subclass.
• This type of casting may not always
succeed.
instanceof
• Use the instanceof operator to test
whether an object is an instance of a class.
Code
• This example creates two geometric
objects: a circle, and a rectangle. It displays
the area and diameter if the object is a
circle, and displays area if the object is a
rectangle.

TestPolymorphismCasting Run
Equality
equals()
• The equals() method compares the
contents of two objects.
• The default implementation of the equals
method in the Object class is as follows
equals()
• You can override equals() method in
your class
ArrayList
ArrayList
• Array’s size is fixed once the array is
created.
• Java provides the ArrayList class that can
be used to store an unlimited number of
objects.
ArrayList
• ArrayList
Program
• ArrayList
• You will get a compilation warning
“unchecked operation.” Ignore it. This
warning can be fixed using generic types in
Chapter 20.

TestArrayList Run
Program
• MyStack MyStack
Accessibility
protected
• Another visibility modifier
• A protected data or a protected method in
a public class can be accessed by any class
in the same package or its subclasses
• Even if the subclasses are in a different
package.
Accessibility
• Accessibility summary
Accessibility
• Accessibility example
Accessibility
•A subclass may override a protected
method in its superclass and change its
visibility to public.
•However, a subclass cannot weaken the
accessibility of a method defined in the
superclass.
•For example, if a method is defined as public
in the superclass, it must be defined as
public in the subclass.
final keyword
final
•A final class cannot be extended

•A final variable is a constant

•A final method cannot be overridden by


its subclasses.
Lecture 23,24
Exception Handling
Objectives
• Chapter 13
• Exceptions
• Exception handling
• Declaring exception
• Throwing exception
• Catching exception
• Different types of exceptions
• Error vs. Exception
• Checked vs. unchecked
• Keywords
• try, catch, finally
• throw, throws
Motivation
• When a program runs into a runtime error, the
program terminates abnormally.
• How can you handle the runtime error so that
the program can continue to run or terminate
gracefully?
Exceptions
Program
• Show runtime error

Quotient Run
Program
• Fix it using an if statement

QuotientWithIf Run
Previously
• Exceptions
• Motivation
Program
• What if the runtime error occurs in a called
method?

QuotientWithException Run
Program
• The advantages of using exception handling:
• It enables a method to throw an exception to its
caller.
• Without this capability, a method must handle the
exception or
• terminate the program.

QuotientWithMethod Run
Program
• By handling InputMismatchException, your
program will continuously read an input until it is
correct.

InputMismatch Run
Exception Hierarchy

• Exception Types
Exception Hierarchy

• “System errors” are thrown by JVM and


represented in the Error class.
• E.g. Linkage error, VirtualMachineError, …
• The Error class describes internal system errors.
• Such errors rarely occur.
• If one does, there is little you can do beyond
notifying the user and trying to terminate the
program gracefully.
Exception Hierarchy

• “Exception” describes errors caused by your


program and external circumstances.
• E.g. RuntimeException, IOException,
ClassNotFoundException, …
• These errors can be caught and handled by your
program.
Exception Hierarchy

• “RuntimeException” is caused by programming


errors, such as bad casting, accessing an
out-of-bounds array, and numeric errors.
• E.g. ArithmaticException, NulPointerException,
IndexOfBoundException,
IllegalArgumentException,…
Checked

• RuntimeException, Error and their subclasses are


known as unchecked exceptions.
• All other exceptions are known as checked
exceptions, meaning that
• the compiler forces the programmer to check and
deal with the exceptions.
Checked

• In most cases, unchecked exceptions reflect


programming logic errors that are not recoverable.
• E.g. NullPointerException or
IndexOutOfBoundsException
• To avoid cumbersome overuse of try-catch blocks,
Java does not mandate you to write code to catch
unchecked exceptions.
Exception Handling

• Exception handling process


1. Declare exception
2. Throw exception
3. Catch exception
Declaring Exception

• Every method must state the types of checked


exceptions it might throw.
• This is known as declaring exceptions.
Throwing Exception

• When the program detects an error, the program


can create an instance of an appropriate
exception type and throw it.
• This is known as throwing an exception.
Throwing Exception

• Example

/** Set a new radius */


public void setRadius(double newRadius)
throws IllegalArgumentException
{
if (newRadius >= 0)
radius = newRadius;
else
throw new IllegalArgumentException(
"Radius cannot be negative");
}
Catching Exception

• Example
Catching Exception

• Exception handling example


Previously

• Exceptions
• Used in conjunction with methods
• 3 steps
• Declare (throws)
• Throw (throw)
• Catch (try-catch)
• Checked vs. unchecked
Catching Exception

• Java forces you to deal with checked exceptions.


• IOException
• If a method declares a checked exception you
must
1. invoke it in a try-catch block or
2. declare to throw the exception in the calling
method.
Catching Exception

• For example, you have to write the code as shown in


(a) or (b).
Catching Exception

• The order in which exceptions are specified in catch


blocks is important.
• A compile error will result if a catch block for a
superclass type appears before a catch block for a
subclass type.
Program
• This example demonstrates declaring, throwing,
and catching exceptions by modifying the
setRadius method in the Circle class.
• The new setRadius method throws an exception if
radius is negative.

TestCircleWithException CircleWithException

Run
Rethrow
• Rethrwoing exceptions
finally
• Occasionally, you may want some code to be
executed regardless of whether an exception
occurs or is caught.
Trace Program
Suppose no exceptions in
the statements

try {
statements;
}
catch(TheException ex) {
//handling ex;
}
finally {
//finalStatements;
}

//Next statement ..
Trace Program

try {
statements;
}
catch(TheException ex) {
//handling ex;
The final block is always
} executed
finally {
//finalStatements;
}

//Next statement ..
Trace Program

try {
statements;
}
catch(TheException ex) {
//handling ex;
}
finally {
//finalStatements; Next statement in the
} method is executed

//Next statement ..
Trace Program
try { Suppose an exception of
statement1; type Exception1 is thrown in
statement2; statement2
statement3;
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x
}
finally {
//finalStatements;
}
//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3;
}
catch(Exception1 ex1) { The exception is handled.
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x
}
finally {
//finalStatements;
}
//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3;
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x The final block is always
} executed.
finally {
//finalStatements;
}
//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3;
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x
}
finally {
//finalStatements; The next statement in the
} method is now executed.

//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3; statement2 throws an
exception of type Exception2.
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x
}
finally {
//finalStatements;
}
//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3;
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x
} Handling exception
finally {
//finalStatements;
}
//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3;
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x
}
finally {
//finalStatements;
}
Execute the final block
//Next statement ..
Trace Program
try {
statement1;
statement2;
statement3;
}
catch(Exception1 ex1) {
//handling ex1;
}
catch(Exception2 ex2) {
//handling ex2;
throw x Rethrow the exception
} and control is
finally { transferred to the caller
//finalStatements;
}
//Next statement ..
Caution!
• Exception handling separates error-handling code
from normal programming tasks.
• Thus making programs easier to read and to
modify.
• Be aware, however, that exception handling
usually requires more time and resources because
it requires
• instantiating a new exception object,
• rolling back the call stack, and
• propagating the errors to the calling methods.
When?
• When to use exceptions:
1. An exception occurs in a method:
• If you want the exception to be processed by its
caller, you should create an exception object and
throw it.
• If you can handle the exception in the method
where it occurs, there is no need to throw it.
When?
• When should you use the try-catch block in the
code?
• You should use it to deal with unexpected error
conditions.
• Do not use it to deal with simple, expected
situations.
When?
• Example
When?
• Same example, better
Custom Exceptions

• Use the exception classes in the API whenever


possible.
• Define custom exception classes if the predefined
classes are not sufficient.
• Define custom exception classes by extending
Exception or a subclass of Exception.
Program
• Custom Exception

InvalidRadiusException

CircleWithRadiusException Run

TestCircleWithRadiusException
Java Remote Object Invocation (RMI)
• Overview of RMI
• Java RMI allowed programmer to execute remote function
calls using the same semantics as local functions calls.
Local Machine (Client) Remote Machine (Server)

SampleServer remoteObject;
int s;

s = remoteObject.sum(1,2);
1,2
public int sum(int a,int b)
{
3 }
return a + b;

System.out.println(s);
The General RMI Architecture
• The server must first bind its
name to the registry
• The client lookup the server
name in the registry to
establish remote references.
• The Stub serializing the
parameters to skeleton, the
skeleton invoking the
remote method and
serializing the result back to
the stub.
The Stub and Skeleton

• A client invokes a remote method, the call is first


forwarded to stub.
• The stub is responsible for sending the remote call over to
the server-side skeleton
• The stub opening a socket to the remote server,
marshaling the object parameters and forwarding the data
stream to the skeleton.
• A skeleton contains a method that receives the remote
calls, unmarshals the parameters, and invokes the actual
remote object implementation.
Steps for Developing an RMI System
1. Define the remote interface
2. Develop the remote object by implementing the remote
interface.
3. Develop the client program.
4. Compile the Java source files.
5. Generate the client stubs and server skeletons.
6. Start the RMI registry.
7. Start the remote server objects.
8. Run the client
Step 1: Defining the Remote Interface
• To create an RMI application, the first step is the defining
of a remote interface between the client and server objects.

/* SampleServer.java */
import java.rmi.*;

public interface SampleServer extends Remote


{
public int sum(int a,int b) throws RemoteException;
}
Step 2: Develop the remote object and its interface
• The server is a simple unicast remote server.
• Create server by extending java.rmi.server.UnicastRemoteObject.
• The server uses the RMISecurityManager to protect its resources
while engaging in remote communication.

/* SampleServerImpl.java */
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;

public class SampleServerImpl extends UnicastRemoteObject


implements SampleServer
{
SampleServerImpl() throws RemoteException
{
super();
}
Step 2: Develop the remote object and its interface
• Implement the remote methods
/* SampleServerImpl.java */
public int sum(int a,int b) throws RemoteException
{
return a + b;
}
}
• The server must bind its name to the registry, the client
will look up the server name.
• Use java.rmi.Naming class to bind the server name
to registry. In this example the name call
“SAMPLE-SERVER”.
• In the main method of your server object, the RMI
security manager is created and installed.
Step 2: Develop the remote object and its interface
/* SampleServerImpl.java */
public static void main(String args[])
{
try
{
System.setSecurityManager(new RMISecurityManager());
//set the security manager

//create a local instance of the object


SampleServerImpl Server = new SampleServerImpl();

//put the local instance in the registry


Naming.rebind("SAMPLE-SERVER" , Server);

System.out.println("Server waiting.....");
}
catch (java.net.MalformedURLException me) {
System.out.println("Malformed URL: " + me.toString()); }
catch (RemoteException re) {
System.out.println("Remote exception: " + re.toString()); }
}
Step 3: Develop the client program
• In order for the client object to invoke methods on the
server, it must first look up the name of server in the
registry. You use the java.rmi.Naming class to
lookup the server name.
• The server name is specified as URL in the from (
rmi://host:port/name )
• Default RMI port is 1099.
• The name specified in the URL must exactly match the
name that the server has bound to the registry. In this
example, the name is “SAMPLE-SERVER”
• The remote method invocation is programmed using the
remote interface name (remoteObject) as prefix and
the remote method name (sum) as suffix.
Step 3: Develop the client program
import java.rmi.*;
import java.rmi.server.*;
public class SampleClient
{
public static void main(String[] args)
{
// set the security manager for the client
System.setSecurityManager(new RMISecurityManager());
//get the remote object from the registry
try
{
System.out.println("Security Manager loaded");
String url = "//localhost/SAMPLE-SERVER";
SampleServer remoteObject = (SampleServer)Naming.lookup(url);
System.out.println("Got remote object");
System.out.println(" 1 + 2 = " + remoteObject.sum(1,2) );
}
catch (RemoteException exc) {
System.out.println("Error in lookup: " + exc.toString()); }
catch (java.net.MalformedURLException exc) {
System.out.println("Malformed URL: " + exc.toString()); }
catch (java.rmi.NotBoundException exc) {
System.out.println("NotBound: " + exc.toString());
}
}
}
Step 4 & 5: Compile the Java source files &
Generate the client stubs and server skeletons
• Assume the program compile and executing
• Once the interface is completed, you need to generate stubs
and skeleton code. The RMI system provides an RMI
compiler (rmic) that takes your generated interface class
and procedures stub code on its self.

> set CLASSPATH=”~/rmi”


> javac SampleServer.java
> javac SampleServerImpl.java
> rmic SampleServerImpl

> javac SampleClient.java


Step 6: Start the RMI registry

• The RMI applications need install to Registry. And the


Registry must start manual by call rmiregisty.
• The rmiregistry us uses port 1099 by default. You can
also bind rmiregistry to a different port by indicating the
new port number as : rmiregistry <new port>

> rmiregistry

• Remark: On Windows, you have to type in from the


command line:
> start rmiregistry
Steps 7 & 8: Start the remote server objects & Run
the client
• Once the Registry is started, the server can be started and
will be able to store itself in the Registry.
• Because of the grained security model in Java 2.0, you
must setup a security policy for RMI by set
java.security.policy to the file policy.all

elpis:~/rmi> java –Djava.security.policy=policy.all


SampleServerImpl

elpis:~/rmi> java –Djava.security.policy=policy.all


SampleClient
Java Policy File

• In Java 2, the java application must first obtain information regarding its
privileges. It can obtain the security policy through a policy file. In above
example, we allow Java code to have all permissions, the contains of the
policy file policy.all is:
grant {
permission java.security.AllPermission;
};
• Now, we given an example for assigning resource permissions:
grant {
permission java.io.filePermission “/tmp/*”, “read”, “write”;
permission java.net.SocketPermission
“somehost.somedomain.com:999”,”connect”;
permission java.net.SocketPermission
“*:1024-65535”,”connect,request”;
permission java.net.SocketPermission “*:80”,”connect”;
};
Comment for the Java Policy File

1. allow the Java code to read/write any files only under the
/tmp directory, includes any subdirectories
2. allow all java classes to establish a network connection
with the host “somehost.somedomain.com” on port 999
3. allows classes to connection to or accept connections on
unprivileged ports greater than 1024 , on any host
4. allows all classes to connect to the HTTP port 80 on any
host.

• You can obtain complete details by following links:


http://java.sun.com/products//jdk/1.2/docs/guide/security/spec/
security-spec.doc3.html
Multi Threading

1
Multi-Tasking
Two kinds of multi-tasking:
1) process-based multi-tasking
2) thread-based multi-tasking
Process-based multi-tasking is about allowing several programs to execute
concurrently, e.g. Java compiler and a text editor.
Processes are heavyweight tasks:
1) that require their own address space
2) inter-process communication is expensive and limited
3) context-switching from one process to another is expensive and limited

2
Thread-Based Multi-Tasking
Thread-based multi-tasking is about a single program executing concurrently
several tasks e.g. a text editor printing and spell-checking text.
Threads are lightweight tasks:
1) they share the same address space
2) they cooperatively share the same process
3) inter-thread communication is inexpensive
4) context-switching from one thread to another is low-cost
Java multi-tasking is thread-based.

3
Reasons for Multi-Threading
Multi-threading enables to write efficient programs that make the maximum
use of the CPU, keeping the idle time to a minimum.
There is plenty of idle time for interactive, networked applications:
1) the transmission rate of data over a network is much slower than the rate
at which the computer can process it
2) local file system resources can be read and written at a much slower rate
than can be processed by the CPU
3) of course, user input is much slower than the computer

4
Single-Threading
In a single-threaded environment, the program has to wait for each of these
tasks to finish before it can proceed to the next.
Single-threaded systems use event loop with pooling:
1) a single thread of control runs in an infinite loop
2) the loop pools a single event queue to decide what to do next
3) the pooling mechanism returns an event
4) control is dispatched to the appropriate event handler
5) until this event handler returns, nothing else can happen

5
Threads: Model
Thread exist in several states:
1) ready to run
2) running
3) a running thread can be suspended
4) a suspended thread can be resumed
5) a thread can be blocked when waiting for a resource
6) a thread can be terminated
Once terminated, a thread cannot be resumed.

6
Threads: Priorities
Every thread is assigned priority – an integer number to decide when to
switch from one running thread to the next (context-switching).
Rules for context switching:
1) a thread can voluntarily relinquish control (sleeping, blocking on I/O,
etc.),then the highest-priority ready to run thread is given the CPU.
2) a thread can be preempted by a higher-priority thread – a lower-priority
thread is suspended
When two equal-priority threads are competing for CPU time, which one is
chosen depends on the operating system.

7
Threads: Synchronization
Multi-threading introduces asynchronous behavior to a program. How to
ensure synchronous behavior when we need it?
For instance, how to prevent two threads from simultaneously writing and
reading the same object?
Java implementation of monitors:
1) classes can define so-called synchronized methods
2) each object has its own implicit monitor that is automatically entered
when one of the object’s synchronized methods is called
3) once a thread is inside a synchronized method, no other thread can call any
other synchronized method on the same object

8
Thread Class
To create a new thread a program will:
1) extend the Thread class, or
2) implement the Runnable interface
Thread class encapsulates a thread of execution.
The whole Java multithreading environment is based on the Thread class.

9
Thread Methods
getName obtain a thread’s name
getPriority obtain a thread’s priority
isAlive determine if a thread is still running
join wait for a thread to terminate
run entry-point for a thread
sleep suspend a thread for a period of time
start start a thread by calling its run method

10
The Main Thread
The main thread is a thread that begins as soon as a program starts.
The main thread:
1) is invoked automatically
2) is the first to start and the last to finish
3) is the thread from which other “child” threads will be spawned
It can be obtained through the
public static Thread currentThread()
method of Thread.

11
Example: Main Thread 1
class CurrentThreadDemo {
public static void main(String args[]) {
The main thread is obtained, displayed, its name changed and re-displayed:
Thread t = Thread.currentThread();
System.out.println("Current thread: " + t);
t.setName("My Thread");
System.out.println("After name change: " + t);

12
Example: Main Thread 2
/* A loop performs five iterations pausing for a second between the iterations.
It is performed within the try/catch block – the sleep method may throw
InterruptedException if some other thread wanted to interrupt:*/
try {
for (int n = 5; n > 0; n--) {
System.out.println(n);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted");
}
}
}

13
Example: Thread Methods
Thread methods used by the example:
1) static void sleep(long milliseconds)
throws InterruptedException
Causes the thread from which it is executed to suspend execution for the
specified number of milliseconds.
2) final String getName()
Allows to obtain the name of the current thread.
3) final void setName(String threadName)
Sets the name of the current thread.

14
Creating a Thread
Two methods to create a new thread:
1) by implementing the Runnable interface
2) by extending the Thread class
We look at each method in order.

15
New Thread: Runnable
To create a new thread by implementing the Runnable interface:
1) create a class that implements the run method (inside this method, we
define the code that constitutes the new thread):
public void run()
2) instantiate a Thread object within that class, a possible constructor is:
Thread(Runnable threadOb, String threadName)
3) call the start method on this object (start calls run):
void start()

16
Example: New Thread 1
A class NewThread that implements Runnable:
class NewThread implements Runnable {
Thread t;
/*Creating and starting a new thread. Passing this to the Thread
constructor – the new thread will call this object’s run method:*/
NewThread() {
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start();
}

17
Example: New Thread 2
/*This is the entry point for the newly created thread – a five-iterations loop with
a half-second pause between the iterations all within try/catch:*/
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}

18
Example: New Thread 3
class ThreadDemo {
public static void main(String args[]) {
/*A new thread is created as an object of NewThread:*/
new NewThread();
/*After calling the NewThread start method, control returns here.*/

19
Example: New Thread 4
/*Both threads (new and main) continue concurrently.
Here is the loop for the main thread:*/
try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}

20
New Thread: Extend Thread
The second way to create a new thread:
1) create a new class that extends Thread
2) create an instance of that class
Thread provides both run and start methods:
1) the extending class must override run
2) it must also call the start method

21
Example: New Thread 1
The new thread class extends Thread:
class NewThread extends Thread {
Create a new thread by calling the Thread’s constructor and start
method:
NewThread() {
super("Demo Thread");
System.out.println("Child thread: " + this);
start();
}

22
Example: New Thread 2
NewThread overrides the Thread’s run method:
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}

23
Example: New Thread 3
class ExtendThread {
public static void main(String args[]) {
After a new thread is created:
new NewThread();
the new and main threads continue concurrently…

24
Example: New Thread 4
This is the loop of the main thread:
try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}

25
New Thread: Which Approach?
The Thread class defines several methods that can be overriden.
Of these methods, only run must be overriden.
Creating a new thread:
1) implement Runnable if only run is overriden
2) extend Thread if other methods are also overriden

26
Example: Multiple Threads 1
So far, we were using only two threads - main and new, but in fact a
program may spawn as many threads as it needs.
NewThread class implements the Runnable interface:
class NewThread implements Runnable {
String name;
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start();
}

27
Example: Multiple Threads 2
Here is the implementation of the run method:
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + "Interrupted");
}
System.out.println(name + " exiting.");
}
}

28
Example: Multiple Threads 3
The demonstration class creates three threads then waits until they all finish:
class MultiThreadDemo {
public static void main(String args[]) {
new NewThread("One");
new NewThread("Two");
new NewThread("Three");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}

29
Using isAlive and join Methods
How can one thread know when another thread has ended?
Two methods are useful:
1) final boolean isAlive() - returns true if the thread upon which it
is called is still running and false otherwise
2) final void join() throws InterruptedException – waits until
the thread on which it is called terminates

30
Example: isAlive and join 1
Previous example improved to use isAlive and join methods.
New thread implements the Runnable interface:
class NewThread implements Runnable {
String name;
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start();
}

31
Example: isAlive and join 2
Here is the new thread’s run method:
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
}

32
Example: isAlive and join 3
class DemoJoin {
public static void main(String args[]) {
Creating three new threads:
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
NewThread ob3 = new NewThread("Three");
Checking if those threads are still alive:
System.out.println(ob1.t.isAlive());
System.out.println(ob2.t.isAlive());
System.out.println(ob3.t.isAlive());

33
Example: isAlive and join 4
Waiting until all three threads have finished:
try {
System.out.println("Waiting to finish.");
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}

34
Example: isAlive and join 5
Testing again if the new threads are still alive:
System.out.println(ob1.t.isAlive());
System.out.println(ob2.t.isAlive());
System.out.println(ob3.t.isAlive());
System.out.println("Main thread exiting.");
}
}

35
Output:DemoJoin-1
• C:\Users\IIIT-Bh\Desktop\java>java DemoJoin
• New thread: Thread[One,5,main]
• New thread: Thread[Two,5,main]
• One: 5
• New thread: Thread[Three,5,main]
• Two: 5
• true
• true
• true
• Three: 5
• Waiting to finish.
• One: 4
• Three: 4

36
Output:DemoJoin-2
• Two: 4
• Three: 3
• Two: 3
• One: 3
• Two: 2
• Three: 2
• One: 2
• Two: 1
37
Output:DemoJoin-3
• Three: 1
• One: 1
• Two exiting.
• One exiting.
• Three exiting.
• false
• false
• false
• Main thread exiting.
38
Thread Priorities
Priority is used by the scheduler to decide when each thread should run.
In theory, higher-priority thread gets more CPU than lower-priority thread
and threads of equal priority should get equal access to the CPU.
In practice, the amount of CPU time that a thread gets depends on several
factors besides its priority.

39
Setting and Checking Priorities
Setting thread’s priority:
final void setPriority(int level)
where level specifies the new priority setting between:
1) MIN_PRIORITY (1)
2) MAX_PRIORITY (10)
3) NORM_PRIORITY (5)
Obtain the current priority setting:
final int getPriority()

40
Example: Priorities 1
A new thread class with click and running variables:
class Clicker implements Runnable {
int click = 0;
Thread t;
private volatile boolean running = true;
A new thread is created, its priority initialised:
public Clicker(int p) {
t = new Thread(this);
t.setPriority(p);
}

41
Example: Priorities 2
When running, click is incremented. When stopped, running is false:
public void run() {
while (running) {
click++;
}
}
public void stop() {
running = false;
}
public void start() {
t.start();
}
}

42
Example: Priorities 3
class HiLoPri {
public static void main(String args[]) {
The main thread is set at the highest priority, the new threads at two above
and two below the normal priority:
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
clicker hi = new clicker(Thread.NORM_PRIORITY + 2);
clicker lo = new clicker(Thread.NORM_PRIORITY - 2);

43
Example: Priorities 4
The threads are started and allowed to run for 10 seconds:
lo.start();
hi.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}

44
Example: Priorities 5
After 10 seconds, both threads are stopped and click variables printed:
lo.stop();
hi.stop();
try {
hi.t.join();
lo.t.join();
} catch (InterruptedException e) {
System.out.println("InterruptedException");
}
System.out.println("Low-priority: " + lo.click);
System.out.println("High-priority: " + hi.click);
}
}

45
Volatile Variable
The volatile keyword is used to declare the running variable:
private volatile boolean running = true;
This is to ensure that the value of running is examined at each iteration of:
while (running) {
click++;
}
Otherwise, Java is free to optimize the loop in such a way that a local copy of
running is created. The use of volatile prevents this optimization.
• The volatile modifier tells the compiler that the variable modified by
volatile can be changed unexpectedly by other parts of the program.

46
Synchronization
When several threads need access to a shared resource, they need some way
to ensure that the resource will be used by only one thread at a time.
This way is called synchronization.
Synchronization uses the concept of monitors:
1) only one thread can enter a monitor at any one time
2) other threads have to wait until the thread exits the monitor
Java implements synchronization in two ways: through the synchronized
methods and through the synchronized statement.

47
Example: No Synchronization 1
The call method tries to print the message string inside brackets, pausing the
current thread for one second in the middle:
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}

48
Example: No Synchronization 2
Caller constructor obtains references to the Callme object and String,
stores them in the target and msg variables, then creates a new thread:
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
}

49
Example: No Synchronization 3
The Caller’s run method calls the call method on the target instance of
Calllme, passing in the msg string:
public void run() {
target.call(msg);
}
}

50
Example: No Synchronization 4
Synch class creates a single instance of Callme and three of Caller,
each with a message. The Callme instance is passed to each Caller:
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");

51
Example: No Synchronization 5
Waiting for all three threads to finish:
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}

52
No Synchronization
Output from the earlier program:
[Hello[Synchronized[World]
]
]
By pausing for one second, the call method allows execution to switch to
another thread. A mix-up of the outputs from of the three message
strings.
In this program, nothing exists to stop all three threads from calling the same
method on the same object at the same time.

53
Synchronized Method
To fix the earlier program, we must serialize the access to call:
class Callme {
synchronized void call(String msg) {

}
}
This prevents other threads from entering call while another thread is using
it. The output result of the program is now as follows:
[Hello]
[Synchronized]
[World]

54
the driver: 3 Threads sharing the
same object
class InternetBankingSystem {
public static void main(String [] args ) {
Account accountObject = new Account ();
Thread t1 = new Thread(new MyThread(accountObject));
Thread t2 = new Thread(new YourThread(accountObject));
Thread t3 = new Thread(new HerThread(accountObject));
t1.start();
t2.start();
t3.start();
// DO some other operation
} // end main()
}
55
Shared account object
between 3 threads
class MyThread implements Runnable {
Account account;
public MyThread (Account s) { account = s;}
public void run() { account.deposit(); }
} // end class MyThread

class YourThread implements Runnable { account


Account account;
public YourThread (Account s) { account = s;}
(shared
public void run() { account.withdraw(); } object)
} // end class YourThread

class HerThread implements Runnable {


Account account;
public HerThread (Account s) { account = s; }
public void run() {account.enquire(); }
} // end class HerThread
56
Monitor (shared object access):
serializes operation on shared object
class Account { // the 'monitor'
int balance;

// if 'synchronized' is removed, the outcome is unpredictable


public synchronized void deposit( ) {
// METHOD BODY : balance += deposit_amount;
}

public synchronized void withdraw( ) {


// METHOD BODY: balance -= deposit_amount;
}
public synchronized void enquire( ) {
// METHOD BODY: display balance.
}
}

57
Synchronized Statement
How to synchronize access to instances of a class that was not designed for
multithreading and we have no access to its source code?
Put calls to the methods of this class inside the synchronized block:
synchronized(object) {

}
This ensures that a call to a method that is a member of the object occurs
only after the current thread has successfully entered the object’s
monitor.

58
Example: Synchronized 1
Now the call method is not modified by synchronized:
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}

59
Example: Synchronized 2
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
}

60
Example: Synchronized 3
The Caller’s run method uses the synchronized statement to include
the call the target’s call method:
public void run() {
synchronized(target) {
target.call(msg);
}
}
}

61
Example: Synchronized 4
class Synch1 {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}

62
Inter-Thread Communication
Inter-thread communication relies on three methods in the Object class:
1) final void wait() throws InterruptedException
tells the calling thread to give up the monitor and go to sleep until some
other thread enters the same monitor and calls notify().
2) final void notify()
wakes up the first thread that called wait() on the same object
3) final void notifyAll()
wakes up all the threads that called wait() on the same object; the
highest-priority thread will run first.
All three must be called from within a synchronized context.

63
Queuing Problem
Consider the classic queuing problem where one thread (producer) is
producing some data and another (consumer) is consuming this data:
1) producer should not overrun the consumer with data
2) consumer should not consume the same data many times
We consider two solutions:
1) incorrect with synchronized only
2) correct with synchronized and wait/notify

64
Example: Incorrect Queue 1
The one-place queue class Q, with the variable n and methods get and
put. Both methods are synchronized:
class Q {
int n;
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}
}

65
Example: Incorrect Queue 2
Producer creates a thread that keeps producing entries for the queue:
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}

66
Example: Incorrect Queue 3
Consumer creates a thread that keeps consuming entries in the queue:
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}

67
Example: Incorrect Queue 4
The PC class first creates a single Queue instance q, then creates a
Producer and Consumer that share this q:
class PC {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}

68
Why Incorrect?
Here is the output:
Put: 1
Got: 1
Got: 1
Put: 2
Put: 3
Get: 3

Nothing stops the producer from overrunning the consumer, nor the
consumer from consuming the same data twice.

69
Example: Corrected Queue 1
The correct producer-consumer system uses wait and notify to
synchronize the behavior of the producer and consumer.
The queue class introduces the additional boolean variable valueSet
used by the get and put methods:
class Q {
int n;
boolean valueSet = false;

70
Example: Corrected Queue 2
Inside get, wait is called to suspend the execution of Consumer until
Producer notifies that some data is ready:
synchronized int get() {
if (!valueSet)
try {
wait();
}
catch(InterruptedException e) {
System.out.println("InterruptedException");
}

71
Example: Corrected Queue 3
After the data has been obtained, get calls notify to tell Producer that it
can put more data on the queue:
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}

72
Example: Corrected Queue 4
Inside put, wait is called to suspend the execution of Producer until
Consumer has removed the item from the queue:
synchronized void put(int n) {
if (valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException");
}

73
Example: Corrected Queue 5
After the next item of data is put in the queue, put calls notify to tell
Consumer that it can remove this item:
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}

74
Example: Corrected Queue 6
Producer creates a thread that keeps producing entries for the queue:
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}

75
Example: Corrected Queue 7
Consumer creates a thread that keeps consuming entries in the queue:
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}

76
Example: Corrected Queue 8
The PCFixed class first creates a single Queue instance q, then creates a
Producer and Consumer that share this q:
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}

77
Deadlock
Multi-threading and synchronization create the danger of deadlock.
Deadlock: a circular dependency on a pair of synchronized objects.
Suppose that:
1) one thread enters the monitor on object X
2) another thread enters the monitor on object Y
3) the first thread tries to call a synchronized method on object Y
4) the second thread tries to call a synchronized method on object X
The result: the threads wait forever – deadlock.

78
Example: Deadlock 1
Class A contains the foo method which takes an instance b of class B as a
parameter. It pauses briefly before trying to call the b’s last method:
class A {
synchronized void foo(B b) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying B.last()");
b.last();
}

79
Example: Deadlock 2
Class A also contains the synchronized method last:
synchronized void last() {
System.out.println("Inside A.last");
}
}

80
Example: Deadlock 3
Class B contains the bar method which takes an instance a of class A as a
parameter. It pauses briefly before trying to call the a’s last method:
class B {
synchronized void bar(A a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying A.last()");
a.last();
}

81
Example: Deadlock 4
Class B also contains the synchronized method last:
synchronized void last() {
System.out.println("Inside A.last");
}
}

82
Example: Deadlock 5
The main Deadlock class creates the instances a of A and b of B:
class Deadlock implements Runnable {
A a = new A();
B b = new B();

83
Example: Deadlock 6
The constructor creates and starts a new thread, and creates a lock on the a
object in the main thread (running foo on a) with b passed as a parameter:
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
a.foo(b);
System.out.println("Back in main thread");
}

84
Example: Deadlock 7
The run method creates a lock on the b object in the new thread (running bar
on b) with a passed as a parameter:
public void run() {
b.bar(a);
System.out.println("Back in other thread");
}
Create a new Deadlock instance:
public static void main(String args[]) {
new Deadlock();
}
}

85
Deadlock Reached
Program output:
MainThread entered A.foo
RacingThread entered B.bar
MainThread trying to call B.last()
RacingThread trying to call A.last()
RacingThread owns the monitor on b while waiting for the monitor on a.
MainThread owns the monitor on a while it is waiting for the monitor on b.
The program deadlocks!

86
Suspending/Resuming Threads
Thread management should use the run method to check periodically
whether the thread should suspend, resume or stop its own execution.
This is usually accomplished through a flag variable that indicates the
execution state of a thread, e.g.
1) running – the thread should continue executing
2) suspend – the thread must pause
3) stop – the thread must terminate

87
Example: Suspending/Resuming 1
NewThread class contains the boolean variable suspendFlag to control
the execution of a thread, initialized to false:
class NewThread implements Runnable {
String name;
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start();
}

88
Example: Suspending/Resuming 2
The run method contains the synchronized statement that checks
suspendFlag. If true, the wait method is called.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) wait();
}
}
}

89
Example: Suspending/Resuming 3
catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}

90
Example: Suspending/Resuming 4
The mysuspend method sets suspendFlag to true:
void mysuspend() {
suspendFlag = true;
}
The myresume method sets suspendFlag to false and invokes notify
to wake up the thread:
synchronized void myresume() {
suspendFlag = false;
notify();
}
}

91
Example: Suspending/Resuming 5
SuspendResume class creates two instances ob1 and ob2 of NewThread,
therefore two new threads, through its main method:
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
The two threads are kept running, then suspended, then resumed from the
main thread:

92
Example: Suspending/Resuming 6
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}

93
Example: Suspending/Resuming 7
The main thread waits for the two child threads to finish, then finishes itself:
try {
System.out.println("Waiting to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}

94
Life Cycle of Thread
new
start()
I/O
completed
ready
Time
resume()
notify() expired/
interrupted
sleeping blocked
waiting
dispatc
h sleep()
wait() suspend()
Block on
running completio I/O
n
stop() dead
95
The Last Word on Multi-Threading
Multi-threading is a powerful tool to writing efficient programs.

When you have two subsystems within a program that can execute
concurrently, make them individual threads.

However, creating too many threads can actually degrade the performance of
your program because of the cost of context switching.

96
Agenda

■ Introduction
■ Elements of Client Server Computing
■ Networking Basics
■ Understanding Ports and Sockets
■ Java Sockets
■ Implementing a Server
■ Implementing a Client
■ Sample Examples
■ Conclusions

1
Introduction

■ Internet and WWW have emerged as global


ubiquitous media for communication and
changing the way we conduct science,
engineering, and commerce.
■ They also changing the way we learn, live,
enjoy, communicate, interact, engage, etc. It
appears like the modern life activities are
getting completely centered around the Internet.

2
Internet Applications Serving Local
and Remote Users

PC client

Internet
Server
Local Area Network

PDA

3
Internet & Web as a delivery Vehicle

4
Increased demand for Internet
applications
■ To take advantage of opportunities presented by
the Internet, businesses are continuously seeking
new and innovative ways and means for offering
their services via the Internet.
■ This created a huge demand for software designers
with skills to create new Internet-enabled
applications or migrate existing/legacy applications
on the Internet platform.
■ Object-oriented Java technologies—Sockets,
threads, RMI, clustering, Web services-- have
emerged as leading solutions for creating portable,
efficient, and maintainable large and complex
Internet applications.
5
Elements of C-S Computing

a client, a server, and network

t
es
qu
Re
Client
Server
Network
Re
su
lt

Client machine
Server machine

6
Networking Basics
■ Applications Layer ■ TCP/IP Stack
■ Standard apps
■ HTTP
■ FTP
■ Telnet Application
■ User apps (http,ftp,telnet,…)
■ Transport Layer
■ TCP Transport
■ UDP (TCP, UDP,..)
■ Programming Interface:
■ Sockets Network
■ Network Layer (IP,..)
■ IP
Link
■ Link Layer
■ Device drivers (device driver,..)

7
Networking Basics

■ TCP (Transport Control ■ TCP/IP Stack


Protocol) is a
connection-oriented Application
protocol that provides a (http,ftp,telnet,…)
reliable flow of data
Transport
between two computers.
(TCP, UDP,..)
■ Example applications: Network
■ HTTP (IP,..)
■ FTP
Link
■ Telnet
(device driver,..)

8
Networking Basics

■ UDP (User Datagram ■ TCP/IP Stack


Protocol) is a protocol
that sends independent Application
packets of data, called (http,ftp,telnet,…)
datagrams, from one
Transport
computer to another with
(TCP, UDP,..)
no guarantees about
Network
arrival.
(IP,..)
■ Example applications:
Link
■ Clock server
(device driver,..)
■ Ping

9
Understanding Ports

■ The TCP and UDP P


o TCP
protocols use ports to server
r Client
map incoming data to t
a particular process
running on a
computer.
app app app app

port port port port


TCP or UDP
Packet
Data port# data
10
Understanding Ports

■ Port is represented by a positive (16-bit) integer


value
■ Some ports have been reserved to support
common/well known services:
■ ftp 21/tcp
■ telnet 23/tcp
■ smtp 25/tcp
■ login 513/tcp
■ User level process/services generally use port
number value >= 1024

11
Sockets

■ Sockets provide an interface for programming networks


at the transport layer.
■ Network communication using Sockets is very much
similar to performing file I/O
■ In fact, socket handle is treated like file handle.
■ The streams used in file I/O operation are also applicable to
socket-based I/O
■ Socket-based communication is programming language
independent.
■ That means, a socket program written in Java language can
also communicate to a program written in Java or non-Java
socket program.

12
Socket Communication
[a]: a client making a connection request to the server
_

■ A server (program) runs on a specific


computer and has a socket that is bound
to a specific port. The server waits and
listens to the socket for a client to make a
connection request.

Connection request
port

server
Client

13
Socket Communication
[b]: session established with temporary ports used for two way communication.

■ If everything goes well, the server accepts the


connection. Upon acceptance, the server gets a new
socket bounds to a different port. It needs a new socket
(consequently a different port number) so that it can
continue to listen to the original socket for connection
requests while serving the connected client.
port

server

port
Client
port Connection

14
Sockets and Java Socket Classes

■ A socket is an endpoint of a two-way


communication link between two
programs running on the network.
■ A socket is bound to a port number so
that the TCP layer can identify the
application that data destined to be sent.
■ Java’s .net package provides two
classes:
■ Socket – for implementing a client
■ ServerSocket – for implementing a server
15
Java Sockets
ServerSocket(1254)
■ server

Output/write stream Client

Input/read stream

Socket(“128.250.25.158”, 1254)
It can be host_name like “mandroo.cs.mu.oz.au” 16
Implementing a Server
1. Open the Server Socket:
ServerSocket server;
DataOutputStream os;
DataInputStream is;
server = new ServerSocket( PORT );
2. Wait for the Client Request:
Socket client = server.accept();
3. Create I/O streams for communicating to the client
is = new DataInputStream( client.getInputStream() );
os = new DataOutputStream( client.getOutputStream() );
4. Perform communication with client
Receive from client: String line = is.readLine();
Send to client: os.writeBytes("Hello\n");
5. Close sockets: client.close();
For multithreaded server:
while(true) {
i. wait for client requests (step 2 above)
ii. create a thread with “client” socket as parameter (the thread creates streams (as in step (3)
and does communication as stated in (4). Remove thread once service is provided.
}
17
Implementing a Client

1. Create a Socket Object:


client = new Socket( server, port_id );
2. Create I/O streams for communicating with the server.
is = new DataInputStream(client.getInputStream() );
os = new DataOutputStream( client.getOutputStream() );
3. Perform I/O or communication with the server:
■ Receive data from the server:
String line = is.readLine();
■ Send data to the server:
os.writeBytes("Hello\n");
4. Close the socket when done:
client.close();

18
A simple server (simplified code)
// SimpleServer.java: a simple server program
import java.net.*;
import java.io.*;
public class SimpleServer {
public static void main(String args[]) throws IOException {
// Register service on port 1254
ServerSocket s = new ServerSocket(1254);
Socket s1=s.accept(); // Wait and accept a connection
// Get a communication stream associated with the socket
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream (s1out);
// Send a string!
dos.writeUTF("Hi there");
// Close the connection, but not the server socket
dos.close();
s1out.close();
s1.close();
}
}
19
A simple client (simplified code)
// SimpleClient.java: a simple client program
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String args[]) throws IOException {
// Open your connection to a server, at port 1254
Socket s1 = new Socket("mundroo.cs.mu.oz.au",1254);
// Get an input file handle from the socket and read the input
InputStream s1In = s1.getInputStream();
DataInputStream dis = new DataInputStream(s1In);
String st = new String (dis.readUTF());
System.out.println(st);
// When done, just close the connection and exit
dis.close();
s1In.close();
s1.close();
}
}

20
Run
■ Run Server on mundroo.cs.mu.oz.au
■ [raj@mundroo] java SimpleServer &

■ Run Client on any machine (including mundroo):


■ [raj@mundroo] java SimpleClient
Hi there

■ If you run client when server is not up:


■ [raj@mundroo] sockets [1:147] java SimpleClient
Exception in thread "main" java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:320)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:133)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:120)
at java.net.Socket.<init>(Socket.java:273)
at java.net.Socket.<init>(Socket.java:100)
at SimpleClient.main(SimpleClient.java:6)

21
Socket Exceptions
try {
Socket client = new Socket(host, port);
handleConnection(client);
}
catch(UnknownHostException uhe) {
System.out.println("Unknown host: " + host);
uhe.printStackTrace();
}
catch(IOException ioe) {
System.out.println("IOException: " + ioe);
ioe.printStackTrace();
}

22
ServerSocket & Exceptions

■ public ServerSocket(int port) throws IOException


■ Creates a server socket on a specified port.
■ A port of 0 creates a socket on any free port. You can use
getLocalPort() to identify the (assigned) port on which this
socket is listening.
■ The maximum queue length for incoming connection
indications (a request to connect) is set to 50. If a connection
indication arrives when the queue is full, the connection is
refused.
■ Throws:
■ IOException - if an I/O error occurs when opening the socket.
■ SecurityException - if a security manager exists and its
checkListen method doesn't allow the operation.

23
Server in Loop: Always up
// SimpleServerLoop.java: a simple server program that runs forever in a single thead
import java.net.*;
import java.io.*;
public class SimpleServerLoop {
public static void main(String args[]) throws IOException {
// Register service on port 1234
ServerSocket s = new ServerSocket(1234);
while(true)
{
Socket s1=s.accept(); // Wait and accept a connection
// Get a communication stream associated with the socket
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream (s1out);
// Send a string!
dos.writeUTF("Hi there");
// Close the connection, but not the server socket
dos.close();
s1out.close();
s1.close();
}
}
}

24
Multithreaded Server: For Serving
Multiple Clients Concurrently

Client 1 Process Server Process

Server
Threads
■ Internet

Client 2 Process

25
Conclusion

■ Programming client/server applications in


Java is fun and challenging.
■ Programming socket programming in
Java is much easier than doing it in other
languages such as C.
■ Keywords:
■ Clients, servers, TCP/IP, port number,
sockets, Java sockets

26
Connection request
server port
Client

■ [a]: a client making a connection request to the server


port

server

port
Client
port Connection

■ [b]: session established with temporary ports used for two way communication.

27
Interface

1
Using interface, we specify what a class must do, but not
how it does this.
An interface is syntactically similar to a class, but it lacks
instance variables and its methods are declared without
any body.
An interface is defined with an interface keyword.

2
Interface Format
General format:
access interface name {
type method-name1(parameter-list);
type method-name2(parameter-list);

type var-name1 = value1;
type var-nameM = valueM;

}

3
Interface Comments
Two types of access:
1) public – interface may be used anywhere in a program
2) default – interface may be used in the current package only
Interface methods have no bodies – they end with the semicolon after
the parameter list. They are essentially abstract methods.
An interface may include variables, but they must be final, static and
initialized with a constant value.
In a public interface, all members are implicitly public.

4
Interface Implementation
A class implements an interface if it provides a complete
set of methods defined by this interface.
1) any number of classes may implement an interface
2) one class may implement any number of interfaces
Each class is free to determine the details of its
implementation.
Implementation relation is written with the implements
keyword.

5
Implementation Format
General format of a class that includes the implements
clause:
access class name
extends super-class
implements interface1, interface2, …, interfaceN {

}
Access is public or default.

6
Implementation Comments
If a class implements several interfaces, they are separated with a
comma.

The methods that implement an interface method must be declared


public.
The type signature of the implementing method must match exactly the
type signature specified in the interface definition.

7
Example: Interface
Declaration of the Callback interface:
interface Callback {
void callback(int param);
}
Client class implements the Callback interface:
class Client implements Callback {
public void callback(int p) {
System.out.println("callback called with " + p);
}
}

8
More Methods in
Implementation
An implementing class may also declare its own methods:
class Client implements Callback {
public void callback(int p) {
System.out.println("callback called with " + p);
}
void nonIfaceMeth() {
System.out.println("Classes that implement “ +
“interfaces may also define ” +
“other members, too.");
}
}
9
Interface as a Type
Variable may be declared with interface as its type:
interface MyInterface { … }

MyInterface mi;
The variable of an interface type may reference an object of
any class that implements this interface.
class MyClass implements MyInterface { … }
MyInterface mi = new MyClass();

10
Call Through Interface Variable
Using the interface type variable, we can call any method in the
interface:
interface MyInterface {
void myMethod(…) ;

}
class MyClass implements MyInterface { … }

MyInterface mi = new MyClass();

mi.myMethod();
The correct version of the method will be called based on the actual
instance of the interface being referred to.
11
Example: Call Through Interface
2
TestIface declares the Callback interface variable,
initializes it with the new Client object, and calls the
callback method through this variable:
class TestIface {
public static void main(String args[]) {
Callback c = new Client();
c.callback(42);
}
}

12
Call Through Interface Variable
2
Call through an interface variable is one of the key features
of interfaces:
1) the method to be executed is looked up dynamically at
run-time
2) the calling code can dispatch through an interface
without having to know anything about the callee

13
Example: Interface Call 1
Another implementation of the Callback interface:
class AnotherClient implements Callback {
public void callback(int p) {
System.out.println("Another version of callback");
System.out.println("p squared is " + (p*p));
}
}

14
Example: Interface Call 2
Callback variable c is assigned Client and later AnotherClient
objects and the corresponding callback is invoked depending on its
value:
class TestIface2 {
public static void main(String args[]) {
Callback c = new Client();
c.callback(42);
AnotherClient ob = new AnotherClient();
c = ob;
c.callback(42);
}
}

15
16
Abstract Class Vs Interface
• Abstract class can define both abstract
and non-abstract methods.
• Interface is a 100-percent abstract class.
• Interface has very little flexibility in how
methods and variables are declared.
• All variable declared in an interface must
be constants i.e. public , static and final.

17
18
Compile-Time Method Binding
Normally, in order for a method to be called from one class to another,
both classes must be present at compile time.
This implies:
1) a static, non-extensible classing environment
2) functionality gets pushed higher and higher in the class hierarchy to
make them available to more sub-classes

19
Run-Time Method Binding
Interfaces support dynamic method binding.
Interface disconnects the method definition from the inheritance
hierarchy:
1) interfaces are in a different hierarchy from classes
2) it is possible for classes that are unrelated in terms of the class
hierarchy to implement the same interface

20
Interface and Abstract Class
A class that claims to implement an interface but does not implement all
its methods must be declared abstract.
Incomplete class implements the Callback interface but not its
callback method, so the class is declared abstract:
abstract class Incomplete implements Callback {
int a, b;
void show() {
System.out.println(a + " " + b);
}
}

21
Example: Stack Interface
Many ways to implement a stack but one interface:
interface IntStack {
void push(int item);
int pop();
}
Lets look at two implementations of this interface:
1) FixedStack – a fixed-length version of the integer stack
2) DynStack – a dynamic-length version of the integer stack

22
Example: FixedStack 1
A fixed-length stack implements the IntStack interface with two private
variables, a constructor and two public methods:
class FixedStack implements IntStack {
private int stck[];
private int tos;
FixedStack(int size) {
stck = new int[size]; tos = -1;
}

23
Example: FixedStack 2
public void push(int item) {
if (tos==stck.length-1)
System.out.println("Stack is full.");
else stck[++tos] = item;
}
public int pop() {
if (tos < 0) {
System.out.println("Stack underflow.");
return 0;
}
else return stck[tos--];
}
}
24
Example: FixedStack 3
A testing class creates two stacks:
class IFTest {
public static void main(String args[]) {
FixedStack mystack1 = new FixedStack(5);
FixedStack mystack2 = new FixedStack(8);

25
Example: FixedStack 4
It pushes and them pops off some values from those stacks:
for (int i=0; i<5; i++) mystack1.push(i);
for (int i=0; i<8; i++) mystack2.push(i);
System.out.println("Stack in mystack1:");
for (int i=0; i<5; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for (int i=0; i<8; i++)
System.out.println(mystack2.pop());
}
}

26
Example: DynStack 1
Another implementation of an integer stack.
A dynamic-length stack is first created with an initial length. The stack is
doubled in size every time this initial length is exceeded.
class DynStack implements IntStack {
private int stck[];
private int tos;
DynStack(int size) {
stck = new int[size];
tos = -1;
}

27
Example: DynStack 2
If stack if full, push creates a new stack with double the size of the old
stack:
public void push(int item) {
if (tos==stck.length-1) {
int temp[] = new int[stck.length * 2];
for (int i=0; i<stck.length; i++)
temp[i] = stck[i];
stck = temp;
stck[++tos] = item;
}
else stck[++tos] = item;
}

28
Example: DynStack 3
If the stack is empty, pop returns the zero value:
public int pop() {
if(tos < 0) {
System.out.println("Stack underflow.");
return 0;
}
else return stck[tos--];
}
}

29
Example: DynStack 4
The testing class creates two dynamic-length stacks:
class IFTest2 {
public static void main(String args[]) {
DynStack mystack1 = new DynStack(5);
DynStack mystack2 = new DynStack(8);

30
Example: DynStack 5
It then pushes some numbers onto those stacks, dynamically
increasing their size, then pops those numbers off:
for (int i=0; i<12; i++) mystack1.push(i);
for (int i=0; i<20; i++) mystack2.push(i);
System.out.println("Stack in mystack1:");
for (int i=0; i<12; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for (int i=0; i<20; i++)
System.out.println(mystack2.pop());
}
}

31
Example: Two Stacks 1
Testing two stack implementations through an interface variable.
First, some numbers are pushed onto both stacks:
class IFTest3 {
public static void main(String args[]) {
IntStack mystack;
DynStack ds = new DynStack(5);
FixedStack fs = new FixedStack(8);
mystack = ds;
for (int i=0; i<12; i++) mystack.push(i);
mystack = fs;
for (int i=0; i<8; i++) mystack.push(i);

32
Example: Two Stacks 2
Then, those numbers are popped off:
mystack = ds;
System.out.println("Values in dynamic stack:");
for (int i=0; i<12; i++)
System.out.println(mystack.pop());
mystack = fs;
System.out.println("Values in fixed stack:");
for (int i=0; i<8; i++)
System.out.println(mystack.pop());
}
}
Which stack implementation is the value of the mystack variable,
therefore which version of push and pop are used, is determined at
run-time. 33
Interface Variables
Variables declared in an interface must be constants.
A technique to import shared constants into multiple classes:
1) declare an interface with variables initialized to the desired values
2) include that interface in a class through implementation
As no methods are included in the interface, the class does not
implement anything except importing the variables as constants.

34
Example: Interface Variables 1
An interface with constant values:
import java.util.Random;
interface SharedConstants {
int NO = 0;
int YES = 1;
int MAYBE = 2;
int LATER = 3;
int SOON = 4;
int NEVER = 5;
}

35
Example: Interface Variables 2
Question implements SharedConstants, including all its constants.
Which constant is returned depends on the generated random number:
class Question implements SharedConstants {
Random rand = new Random();
int ask() {
int prob = (int) (100 * rand.nextDouble());
if (prob < 30) return NO;
else if (prob < 60) return YES;
else if (prob < 75) return LATER;
else if (prob < 98) return SOON;
else return NEVER;
}
}
36
Example: Interface Variables 3
AskMe includes all shared constants in the same way, using them to
display
the result, depending on the value received:
class AskMe implements SharedConstants {
static void answer(int result) {
switch(result) {
case NO: System.out.println("No"); break;
case YES: System.out.println("Yes"); break;
case MAYBE: System.out.println("Maybe"); break;
case LATER: System.out.println("Later"); break;
case SOON: System.out.println("Soon"); break;
case NEVER: System.out.println("Never"); break;
}
} 37
Example: Interface Variables 4
The testing function relies on the fact that both ask and answer
methods, defined in different classes, rely on the same constants:
public static void main(String args[]) {
Question q = new Question();
answer(q.ask());
answer(q.ask());
answer(q.ask());
answer(q.ask());
}
}

38
Interface Inheritance
One interface may inherit another interface.
The inheritance syntax is the same for classes and interfaces.
interface MyInterface1 {
void myMethod1(…) ;
}
interface MyInterface2 extends MyInterface1 {
void myMethod2(…) ;
}
When a class implements an interface that inherits another interface, it
must
provide implementations for all methods defined within the interface
inheritance chain.

39
Inheritance and Implementation
When a class implements an interface that inherits another interface, it
must
provide implementations for all inherited methods:
class MyClass implements MyInterface2 {
void myMethod1(…) { … }
void myMethod1(…) { … }

}

40
Example: Interface Inheritance 1
Consider interfaces A and B.
interface A {
void meth1();
void meth2();
}
B extends A:
interface B extends A {
void meth3();
}

41
Example: Interface Inheritance 2
MyClass must implement all of A and B methods:
class MyClass implements B {
public void meth1() {
System.out.println("Implement meth1().");
}
public void meth2() {
System.out.println("Implement meth2().");
}
public void meth3() {
System.out.println("Implement meth3().");
}
}

42
Example: Interface Inheritance 3
Create a new MyClass object, then invoke all interface methods on it:
class IFExtend {
public static void main(String arg[]) {
MyClass ob = new MyClass();
ob.meth1();
ob.meth2();
ob.meth3();
}
}

43
JDBC and Database Programming
in Java
Agenda
• Overview of Databases and Java
• Overview of JDBC
• JDBC APIs
• Other Database Techniques
Database Architectures
• Two-tier
• Three-tier
• N-tier
Two-Tier Architecture
• Client connects directly to server
• e.g. HTTP, email
• Pro:
– simple
– client-side scripting offloads work onto the client
• Con:
– fat client
– inflexible
Three-Tier Architecture
• Application Server sits between client and
database
Three-Tier Pros
• flexible: can change one part without affecting
others
• can connect to different databases without
changing code
• specialization: presentation / business logic /
data management
• can cache queries
• can implement proxies and firewalls
Three-Tier Cons
• higher complexity
• higher maintenance
• lower network efficiency
• more parts to configure (and buy)
N-Tier Architecture
• Design your application using as many “tiers”
as you need
• Use Object-Oriented Design techniques
• Put the various components on whatever host
makes sense
• Java allows N-Tier Architecture, especially
with RMI and JDBC
Database Technologies
• Hierarchical
– obsolete (in a manner of speaking)
– any specialized file format can be called a hierarchical DB
• Relational (aka SQL) (RDBMS)
– row, column
– most popular
• Object-relational DB (ORDBMS)
– add inheritance, blobs to RDB
– NOT object-oriented -- “object” is mostly a marketing term
• Object-oriented DB (OODB)
– data stored as objects
– high-performance for OO data models
Relational Databases
• invented by Dr. E.F.Codd
• data stored in records which live in tables
• maps row (record) to column (field) in a single
table
• “relation” (as in “relational”) means row to
column (not table to table)
Joining Tables
• you can associate tables with one another
• allows data to nest
• allows arbitrarily complicated data structures
• not object-oriented
Join example
• People
– name
– homeaddress
– workaddress
• Addresses
– id
– street
– state
– zip
SQL
• Structured Query Language
• Standardized syntax for “querying” (accessing)
a relational database
• Supposedly database-independent
• Actually, there are important variations from
DB to DB
SQL Syntax
INSERT INTO table ( field1, field2 ) VALUES (
value1, value2 )
– inserts a new record into the named table
UPDATE table SET ( field1 = value1, field2 =
value2 ) WHERE condition
– changes an existing record or records
DELETE FROM table WHERE condition
– removes all records that match condition
SELECT field1, field2 FROM table WHERE
condition
– retrieves all records that match condition
Transactions
• Transaction = more than one statement which
must all succeed (or all fail) together
• If one fails, the system must reverse all
previous actions
• Also can’t leave DB in inconsistent state
halfway through a transaction
• COMMIT = complete transaction
• ROLLBACK = abort
Part II: JDBC Overview
JDBC Goals
• SQL-Level
• 100% Pure Java
• Keep it simple
• High-performance
• Leverage existing database technology
– why reinvent the wheel?
• Use strong, static typing wherever possible
• Use multiple methods to express multiple
functionality
JDBC Architecture

Applicati
JDBC Driver
on

• Java code calls JDBC library


• JDBC loads a driver
• Driver talks to a particular database
• Can have more than one driver -> more than one
database
• Ideal: can change database engines without changing
any application code
JDBC Drivers
• Type I: “Bridge”
• Type II: “Native”
• Type III: “Middleware”
• Type IV: “Pure”
JDBC Drivers (Fig.)

Type I ODBC
ODBC
“Bridge” Driver

Type II CLI
JDBC “Native” (.lib)

Type III Middle


“Middle ware
ware” Server

Type IV
“Pure”
Type I Drivers
• Use bridging technology
• Requires installation/configuration on client
machines
• Not good for Web
• e.g. ODBC Bridge
Type II Drivers
• Native API drivers
• Requires installation/configuration on client
machines
• Used to leverage existing CLI libraries
• Usually not thread-safe
• Mostly obsolete now
• e.g. Intersolv Oracle Driver, WebLogic drivers
Type III Drivers
• Calls middleware server, usually on database
host
• Very flexible -- allows access to multiple
databases using one driver
• Only need to download one driver
• But it’s another server application to install
and maintain
• e.g. Symantec DBAnywhere
Type IV Drivers
• 100% Pure Java -- the Holy Grail
• Use Java networking libraries to talk directly
to database engines
• Only disadvantage: need to download a new
driver for each database engine
• e.g. Oracle, mSQL
Part III: JDBC APIs
java.sql
• JDBC is implemented via classes in the java.sql
package
Loading a Driver Directly
Driver d = new
foo.bar.MyDriver();
Connection c = d.connect(...);
• Not recommended, use DriverManager
instead
• Useful if you know you want a particular
driver
DriverManager
• DriverManager tries all the drivers
• Uses the first one that works
• When a driver class is first loaded, it registers
itself with the DriverManager
• Therefore, to register a driver, just load it!
Registering a Driver
• statically load driver
Class.forName(“foo.bar.MyDriver”);
Connection c =
DriverManager.getConnection(...);
• or use the jdbc.drivers system
property
JDBC Object Classes
• DriverManager
– Loads, chooses drivers
• Driver
– connects to actual database
• Connection
– a series of SQL statements to and from the DB
• Statement
– a single SQL statement
• ResultSet
– the records returned from a Statement
JDBC Class Usage
DriverManager

Driver

Connection

Statement

ResultSet
JDBC URLs
jdbc:subprotocol:source
• each driver has its own subprotocol
• each subprotocol has its own syntax for the
source
jdbc:odbc:DataSource
– e.g. jdbc:odbc:Northwind
jdbc:msql://host[:port]/database
– e.g. jdbc:msql://foo.nowhere.com:4333/accounting
DriverManager
Connection getConnection
(String url, String user,
String password)
• Connects to given JDBC URL with given user
name and password
• Throws java.sql.SQLException
• returns a Connection object
Connection
• A Connection represents a session with a specific database.
• Within the context of a Connection, SQL statements are
executed and results are returned.
• Can have multiple connections to a database
– NB: Some drivers don’t support serialized connections
– Fortunately, most do (now)
• Also provides “metadata” -- information about the database,
tables, and fields
• Also methods to deal with transactions
Obtaining a Connection

String url = "jdbc:odbc:Northwind";


try {
Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection(url);
}
catch (ClassNotFoundException e)
{ e.printStackTrace(); }
catch (SQLException e)
{ e.printStackTrace(); }
Connection Methods
Statement createStatement()
– returns a new Statement object
PreparedStatement prepareStatement(String
sql)
– returns a new PreparedStatement object
CallableStatement prepareCall(String sql)
– returns a new CallableStatement object
• Why all these different kinds of statements?
Optimization.
Statement
• A Statement object is used for executing a
static SQL statement and obtaining the results
produced by it.
Statement Methods
ResultSet executeQuery(String)
– Execute a SQL statement that returns a single ResultSet.
int executeUpdate(String)
– Execute a SQL INSERT, UPDATE or DELETE statement.
Returns the number of rows changed.
boolean execute(String)
– Execute a SQL statement that may return multiple results.
• Why all these different kinds of queries?
Optimization.
ResultSet
• A ResultSet provides access to a table of data
generated by executing a Statement.
• Only one ResultSet per Statement can be open at
once.
• The table rows are retrieved in sequence.
• A ResultSet maintains a cursor pointing to its current
row of data.
• The 'next' method moves the cursor to the next row.
– you can’t rewind
ResultSet Methods
• boolean next()
– activates the next row
– the first call to next() activates the first row
– returns false if there are no more rows
• void close()
– disposes of the ResultSet
– allows you to re-use the Statement that created it
– automatically called by most Statement methods
ResultSet Methods
• Type getType(int columnIndex)
– returns the given field as the given type
– fields indexed starting at 1 (not 0)
• Type getType(String columnName)
– same, but uses name of field
– less efficient
• int findColumn(String columnName)
– looks up column index given column name
ResultSet Methods
• String getString(int columnIndex)
• boolean getBoolean(int columnIndex)
• byte getByte(int columnIndex)
• short getShort(int columnIndex)
• int getInt(int columnIndex)
• long getLong(int columnIndex)
• float getFloat(int columnIndex)
• double getDouble(int columnIndex)
• Date getDate(int columnIndex)
• Time getTime(int columnIndex)
• Timestamp getTimestamp(int columnIndex)
ResultSet Methods
• String getString(String columnName)
• boolean getBoolean(String columnName)
• byte getByte(String columnName)
• short getShort(String columnName)
• int getInt(String columnName)
• long getLong(String columnName)
• float getFloat(String columnName)
• double getDouble(String columnName)
• Date getDate(String columnName)
• Time getTime(String columnName)
• Timestamp getTimestamp(String columnName)
isNull
• In SQL, NULL means the field is empty
• Not the same as 0 or “”
• In JDBC, you must explicitly ask if a field is null
by calling ResultSet.isNull(column)
Sample Database
Employee ID Last Name First Name
1 Davolio Nancy
2 Fuller Andrew
3 Leverling Janet
4 Peacock Margaret
5 Buchanan Steven
SELECT Example
Connection con =
DriverManager.getConnection(url, "alex",
"8675309");
Statement st = con.createStatement();
ResultSet results = st.executeQuery("SELECT
EmployeeID, LastName, FirstName FROM
Employees");
SELECT Example (Cont.)
while (results.next()) {
int id = results.getInt(1);
String last = results.getString(2);
String first = results.getString(3);
System.out.println("" + id + ": " + first
+ " " + last);
}
st.close();
con.close();
Mapping Java Types to SQL Types
SQL type Java Type
CHAR, VARCHAR, LONGVARCHAR String
NUMERIC, DECIMAL java.math.BigDecimal
BIT boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT, DOUBLE double
BINARY, VARBINARY, LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
Database Time
• Times in SQL are notoriously unstandard
• Java defines three classes to help
• java.sql.Date
– year, month, day
• java.sql.Time
– hours, minutes, seconds
• java.sql.Timestamp
– year, month, day, hours, minutes, seconds, nanoseconds
– usually use this one
Modifying the Database
• use executeUpdate if the SQL contains
“INSERT” or “UPDATE”
• Why isn’t it smart enough to parse the SQL?
Optimization.
• executeUpdate returns the number of rows
modified
• executeUpdate also used for “CREATE TABLE”
etc. (DDL)
Transaction Management
• Transactions are not explicitly opened and
closed
• Instead, the connection has a state called
AutoCommit mode
• if AutoCommit is true, then every statement is
automatically committed
• default case: true
setAutoCommit
Connection.setAutoCommit(boolean)
• if AutoCommit is false, then every statement is
added to an ongoing transaction
• you must explicitly commit or rollback the
transaction using Connection.commit() and
Connection.rollback()
Connection Managers
• Hint: for a large threaded database server, create a
Connection Manager object
• It is responsible for maintaining a certain number of open
connections to the database
• When your applications need a connection, they ask for one
from the CM’s pool
• Why? Because opening and closing connections takes a long
time
• Warning: the CM should always setAutoCommit(false) when a
connection is returned
Optimized Statements
• Prepared Statements
– SQL calls you make again and again
– allows driver to optimize (compile) queries
– created with Connection.prepareStatement()
• Stored Procedures
– written in DB-specific language
– stored inside database
– accesed with Connection.prepareCall()

You might also like