Advanced Programming Language 2 Lecture 0 – Course Introduction (3)
Advanced Programming Language 2 Lecture 0 – Course Introduction (3)
• Final 50
• Midterm 20
• Practical Quizzes 20
• Project 15
• Note total semester work grade is 50
• If the student gets a mark above 50, he will only
get 50.
Section
• Get involved with the story.
Practice.. Practice.. Practice..
Course Project Policy
01 02 03
Project groups: Each Project Must be GUI can be
group will be 4 to 5 implemented based implemented using
students. om MVC concept Swing or
Javafx[Bounce]
Academic Integrity
• Integrated Development Environment (IDE): IDE provides a sophisticated GUI and editor, with
integrated facilities for compiling, running, and debugging programs
• Java 2 Standard Edition SDK (Software Development Kit): //What we need..
• SDK includes everything you need to compile and run Java.
• SDK tools are used for compiling and running Java programs on a variety of platforms
• The Java compiler (javac) translates Java source into bytecode.
• The Java interpreter (java) translates and executes Java bytecode. Java interpreters are
available for many different computer systems.
• Java 2 Enterprise Edition (J2EE) → for large-scale systems
• Java 2 Micro Edition (J2ME) → for mobile phones
• Java 2 Standard Edition (J2SE) – Our Course -
Java Setting up
• We can work with Netbeans/Eclipse/ IntelliJ
• https://netbeans.org/downloads/
• https://eclipse.org/downloads/
• JDK
http://www.oracle.com/technetwork/java/javase/dow
nloads/index.html
• Java documentation https://docs.oracle.com/javase
Java Setting up For JavaFX
• Install first the JDK and We will use Zulu JDK-fx
• Java Download | Java 7, Java 8, Java 11, Java 13, Java 15, Java 17, Java
19 - Linux, Windows & macOS (azul.com)
• IntelliJ IDEA Community Edition
• Download IntelliJ IDEA: The Capable & Ergonomic Java IDE by
JetBrains
• We will use Scene Builder for GUI (Drag & Drop)
• Scene Builder - Gluon (gluonhq.com)
Video for
Configuration
• https://youtu.be/LTgClBqDank
What Is JDK?
The most important part of JDK and JRE is JVM ( Java Virtual Machine) and its
responsibility is the execution of code line-by-line. It's also known as an Interpreter. In the
following, we will get more acquainted with it.
Java Virtual Machine (JVM)
• The Java Virtual Machine is a specification that provides a runtime
environment in which java bytecode can be executed. It means JVM
creates a platform to run Java bytecode(.class file) and converting into
different languages (native machine language) which the computer
hardware can understand. Actually, there is nothing to install as JVM.
When the JRE is installed, it will deploy the code to create a JVM for
the particular platform. JVMs are available for many hardware and
software platforms.
How does Java Code Compile And Run?
Java (JRE)
(JVM)
javac
[ JIT ]
How does Java Code Compile And Run?
• Step 3: This is the start of the Run Time phase, where the bytecode is
loaded into the JVM by the class loader(another inbuilt program inside the
JVM).
• Step 4: Now the bytecode verifier checks the bytecode for its integrity and
if no issues are found passes it to the interpreter. For example, if in the
program, we use a variable that has not been declared, or if the run-time
stack overflows, it will throw an Exception and the compiling process will
stop.
• Step 5: Since java is both compiled and interpreted language, now the java
interpreter and Just in time Compiler (JIT) inside the JVM convert the
bytecode into executable machine code and passed it to the OS/Hardware
i.e. the CPU to execute.
Just in time Compiler (JIT)
• The JIT compiler allows Java to be both a compiled and
interpreted language. It combines the performance advantage
of a compiled language with the flexibility of an interpreted
language.
• While the JVM interprets bytecode, the JIT analyses execution
and dynamically compiles frequently executed bytecode to
machine code. This prevents the JVM from having to interpret
the same bytecode over and over.
How the JIT Compiler Works in Java
• The source code you write (.java) is compiled by javac to
bytecode. When your program executes, the JVM starts
interpreting this bytecode.
• The interpreter translates the bytecode into machine code and
feeds it to the CPU for processing.
• While this happens, the JIT profiles and analyses the code
execution. It tracks the most frequently called methods and
dynamically compiles these to machine code at runtime.
JVM(Java Virtual Machine)
• JVM(Java Virtual Machine) runs Java applications as a run-
time engine. JVM is the one that calls the main method present
in a Java code. JVM is a part of JRE(Java Runtime Environment).
• Java applications are called WORA (Write Once Run
Anywhere). This means a programmer can develop Java code
on one system and expect it to run on any other Java-enabled
system without any adjustment. This is all possible because of
JVM.
What is a JVM in Java?
• There are three main mechanisms inside the JVM as shown in the
above diagram.
• ClassLoader
• Memory Area
• Execution Engine
Next Lecture
What is a
JVM
in Java ?
Class
Loader
• The first class to be loaded
into memory is usually the
class that contains the
main() method.
• There are three phases in
the class loading process:
loading, linking, and
initialization.
Class Loader - Loading
• Bootstrap Class Loader - This is the root class loader. It is the superclass of
Extension Class Loader and loads the standard Java packages like java.lang,
java.net, java.util, java.io, and so on. These packages are present inside the
rt.jar file and other core libraries present in the $JAVA_HOME/jre/lib
directory.
• Extension Class Loader - This is the subclass of the Bootstrap Class Loader
and the superclass of the Application Class Loader. This loads the
extensions of standard Java libraries which are present in the
$JAVA_HOME/jre/lib/ext directory.
• Application Class Loader - This is the final class loader and the subclass of
Extension Class Loader. It loads the files present on the classpath. By
default, the classpath is set to the current directory of the application. The
classpath can also be modified by adding the -classpath or -cp command
line option.
Class Loader - Loading
• The JVM uses the ClassLoader.loadClass() method for loading the
class into memory.
• If a parent class loader is unable to find a class, it delegates the work
to a child class loader. If the last child class loader isn't able to load
the class either, it throws NoClassDefFoundError or
ClassNotFoundException.
Class Loader - Linking - Verification
• After a class is loaded into memory, it undergoes the linking process.
Linking a class or interface involves combining the different elements
and dependencies of the program together.
• Linking includes the following steps:
• Verification: This phase checks the structural correctness of the .class
file by checking it against a set of constraints or rules. If verification
fails for some reason, we get a VerifyException.
• For example, if the code has been built using Java 11, but is being run
on a system that has Java 8 installed, the verification phase will fail.
Class Loader - Linking - Preparation
• Preparation: After a Java virtual machine has loaded a class and
performed whatever verification it chooses to do up front, the class is
ready for preparation. During the preparation phase, the Java virtual
machine allocates memory for the class variables and sets them to
default initial values. The class variables are not initialized to their
proper initial values until the initialization phase. (No Java code is
executed during the preparation step.) During preparation, the Java
virtual machine sets the newly allocated memory for the class
variables to a default value determined by the type of the variable.
Class Loader - Linking - Resolution
• Resolution
• Resolution involves replacing symbolic references in the bytecode with
actual references to memory locations. In the class file, references to other
classes, methods, or fields are stored symbolically (using names or
constants), and during resolution, these are mapped to actual addresses in
memory.
• The JVM resolves symbolic references like class names, field names, and
method signatures into direct references that point to actual memory
addresses.
• It links classes with their superclasses and interfaces.
• The symbolic references are replaced with concrete references, allowing
the JVM to call methods and access fields directly.
Class Loader - Initialization
• Initialization involves executing the initialization method of the class
or interface (known as <clinit>).
• This can include calling the class's constructor, executing the static
block, and assigning values to all the static variables. This is the final
stage of class loading.
Runtime Data Area
• There are five components inside the runtime data area:
•
Runtime Data Area - method area
• method area is shared among all Java Virtual Machine threads. The
method area is analogous to the storage area for compiled code of a
conventional language or analogous to the "text" segment in an
operating system process. It stores per-class structures such as the
run-time constant pool, field and method data, and the code for
methods and constructors, including the special methods used in
class and instance initialization and interface initialization.
• In the method area, all class level information like class name,
immediate parent class name, methods and variables information etc.
are stored, including static variables. There is only one method area
per JVM, and it is a shared resource.
Runtime Data Area - heap area
• The Java Virtual Machine has a heap that is shared among all
Java Virtual Machine threads. The heap is the run-time data
area from which memory for all class instances and arrays is
allocated.
• All the objects and their corresponding instance variables are
stored here.
• Note: Since the Method and Heap areas share the same memory
for multiple threads, the data stored here is not thread safe.
Runtime Data Area - Stack area
• Stack area: For every thread, JVM creates one run-time stack
which is stored here. Every block of this stack is called
activation record/stack frame which stores methods calls. All
local variables of that method are stored in their corresponding
frame. After a thread terminates, its run-time stack will be
destroyed by JVM. It is not a shared resource.
• Note: Since the Stack Area is not shared, it is inherently thread
safe.
•
Runtime Data Area
• PC Registers: Store address of current execution instruction of
a thread. Obviously, each thread has separate PC Registers.
• Native method stacks: The JVM contains stacks that
support native methods. These methods are written in a language
other than the Java, such as C and C++. For every new thread, a
separate native method stack is also allocated..
Execution Engine
• Once the bytecode has been loaded into the main memory, and
details are available in the runtime data area, the next step is to
run the program. The Execution Engine handles this by executing
the code present in each class.
Execution Engine
• Interpreter
• The interpreter reads and executes the bytecode instructions line by line.
Due to the line by line execution, the interpreter is comparatively slower.
• Another disadvantage of the interpreter is that when a method is called
multiple times, every time a new interpretation is required.
• JIT Compiler
• The JIT Compiler overcomes the disadvantage of the interpreter. The
Execution Engine first uses the interpreter to execute the byte code, but
when it finds some repeated code, it uses the JIT compiler.
• The JIT compiler then compiles the entire bytecode and changes it to native
machine code. This native machine code is used directly for repeated
method calls, which improves the performance of the system.
Execution Engine
• The JIT Compiler has the following components:
1.Intermediate Code Generator - generates intermediate code
2.Code Optimizer - optimizes the intermediate code for better
performance
3.Target Code Generator - converts intermediate code to native
machine code
4.Profiler - finds the hotspots (code that is executed repeatedly)
Execution Engine
• An interpreter will fetch the value of sum
from memory for each iteration in the loop,
add the value of i to it, and write it back to
memory. This is a costly operation because
it is accessing the memory each time it
enters the loop.
• However, the JIT compiler will recognize
that this code has a HotSpot, and will
perform optimizations on it. It will store a
local copy of sum in the PC register for the
thread and will keep adding the value of i to
it in the loop. Once the loop is complete, it
will write the value of sum back to memory.
Garbage Collector
• Garbage collection makes Java memory efficient because because it
removes the unreferenced objects from heap memory and makes
free space for new objects. It involves two phases:
• Mark - in this step, the GC identifies the unused objects in memory
• Sweep - in this step, the GC removes the objects identified during the
previous phase
• Garbage Collections is done automatically by the JVM at regular
intervals and does not need to be handled separately. It can also be
triggered by calling System.gc(), but the execution is not guaranteed.
Java Native Interface (JNI)
• At times, it is necessary to use native (non-Java) code (for example, C/C++). This
can be in cases where we need to interact with hardware, or to overcome the
memory management and performance constraints in Java. Java supports the
execution of native code via the Java Native Interface (JNI).
• JNI acts as a bridge for permitting the supporting packages for other
programming languages such as C, C++, and so on. This is especially helpful in
cases where you need to write code that is not entirely supported by Java, like
some platform specific features that can only be written in C.
• You can use the native keyword to indicate that the method implementation
will be provided by a native library. You will also need to invoke
System.loadLibrary() to load the shared native library into memory, and make
its functions available to Java.
Native Method Libraries
• Native Method Libraries are libraries that are written in other
programming languages, such as C, C++, and assembly.
• These libraries are usually present in the form of .dll or .so files. These
native libraries can be loaded through JNI.
References
• Java: How To Program, Early Objects, 11th edition
• Setup IntelliJ IDEA (2021) for JavaFX & SceneBuilder and Create Your First JavaFX Application – YouTube
• Introduction to Java Programming and Data Structures, Comprehensive Version 12th Edition, by
Y. Liang (Author), Y. Daniel Liang
• Java documentation https://docs.oracle.com/javase
• https://www.youtube.com/watch?v=LTgClBqDank&feature=youtu.be
• Understanding Java Virtual Machine (JVM) Architecture | by Jalitha Dewapura | Java For Beginners | Medium
• JVM Tutorial - Java Virtual Machine Architecture Explained for Beginners (freecodecamp.org)
• How JVM Works - JVM Architecture – GeeksforGeeks
• Chapter 2. The Structure of the Java Virtual Machine (oracle.com)
• JVM Internals (jamesdbloom.com)
Usage of native in Java - Stack Overflow
Java Type Loading, Linking, and Initialization (artima.com)
Thanks
Advanced Programming Language
Dr. Ahmed Hesham Mostafa
Dr. Mohamed Atia
Lectures 1 – Java Basics
• Class name
• Main method
Java • Statements
Program • Statement terminator
Components • Reserved words
• Comments
• Blocks
2
Class Name
• Every Java program must have at least one class.
• Each class has a name.
• By convention, class names start with an uppercase letter.
• In this example, the class name is Welcome.
3
Main Method
• Line 2 defines the main method.
• In order to run a class, the class must contain a method named main.
• The program is executed from the main method.
4
Statement
• A statement represents an action or a sequence of actions.
• The statement System.out.println("Welcome to Java!") in the program
displays the greeting "Welcome to Java!“.
5
Statement Terminator
Every statement in Java ends with a semicolon (;).
6
Keywords
• Keywords are words that have a specific meaning to the compiler and
cannot be used for other purposes in the program.
• For example, when the compiler sees the word class, it understands
that the word after class is the name for the class.
7
Blocks
• A pair of braces in a program forms a block that groups
components of a program.
8
Special Symbols
" " Opening and closing Enclosing a string (i.e., sequence of characters).
quotation marks
; Semicolon Marks the end of a statement.
9
Reading Input from the Console
• 1. Import Scanner class
import java.util.Scanner;
• 2. Create a Scanner object
Scanner input = new Scanner(System.in);
• 3. Use the methods next(), nextByte(), nextShort(), nextInt(), nextLong(),
nextFloat(), nextDouble(), or nextBoolean() to obtain to a string, byte, short, int,
long, float, double, or boolean value. For example,
System.out.print("Enter a double value: ");
Scanner input = new Scanner(System.in);
double d = input.nextDouble();
10
Methods for Scanner Objects
11
import java.util.Scanner;
Example public class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in);
System.out.println("Enter name, age and salary:");
String name = myObj.nextLine();
int age = myObj.nextInt();
double salary = myObj.nextDouble();
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Salary: " + salary);
}
}
Example
Output
An identifier is a sequence of characters that consists of
letters, digits, underscores (_), and dollar signs ($).
14
Data types
Java is a strongly typed language
• This means that every variable and expression has a type when the program is compiled and
that you cannot arbitrarily assign values of one type to another.
15
Primitive Data Types
Data types
Declaration and initialization:
• we can reserve memory locations for storing values of any primitive type. Those
memory locations can then be made to contain values that are legal for the particular
type. This involves two steps.
1) Declaration: Create a variable of the type you want to use.
2) Initialization: This refers to when you first store something useful in a variable's
memory location.
-Case sensitive
Do not
-use Reserved words
-start with number
17
• Constants “you can not change the value”
Data types
18
Data types
Casting
• There are occasions where we want to be able to convert from one type to another. This
can be done either:
• Automatically: Java does it for us.
• By casting: we have to specify a type conversion.
• By writing the desired type of an expression in parentheses in front of the
expression; for example, write (int) in front of an expression if we wanted it to be
converted to an int.
• Note that the fractional parts of a float data type are lost if casting to an integral type.
Ex. Casting a double to an int. Example: Casting an int to a char
c will have the value
60, which is the 61st
character in the
Unicode set. This
turns out to be the
character '<'.
intVal will have the value of 2
19
Example
public class Main { Output
public static void main(String[] args) {
double doubleVal=2.8;
int intVal= (int) doubleVal;
System.out.println("intVal = "+intVal);
int a=35,b=12,d=13;
char valC=(char)(a+b+d);
System.out.println("valC = "+valC);
}
}
Data types
• When is a cast required?
• A cast is required if the type you are assigning (on the right-hand side of an
equals sign) occupies a larger space in memory than the type you are
assigning to (on the left-hand side of an equals sign).
• If you have not specified a cast in a case where a cast is required, the compiler
will produce a compilation error with the message that there is a 'possible
loss of precision.
23
Strings
More string methods
24
Example
public class Main {
public static void main(String[] args) {
26
Reading a Character from the
Console
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a character: ");
String s = input.nextLine();
char ch = s.charAt(0);
System.out.println("The character entered is " + ch);
}
}
27
Comparing Strings
Method Description
Note : the == operator is used to compare two object references to see whether they refer to the same instance.
28
Obtaining Substrings
Method Description
substring(beginIndex) Returns this string’s substring that begins with the character at the specified
beginIndex and extends to the end of the string, as shown in Figure 4.2.
substring(beginIndex, Returns this string’s substring that begins at the specified beginIndex and
endIndex) extends to the character at index endIndex – 1, as shown in Figure 9.6.
Note that the character at endIndex is not part of the substring.
29
Finding a Character or a Substring in a
String
Method Description
indexOf(ch) Returns the index of the first occurrence of ch in the string. Returns -1 if not
matched.
indexOf(ch, fromIndex) Returns the index of the first occurrence of ch after fromIndex in the string.
Returns -1 if not matched.
indexOf(s) Returns the index of the first occurrence of string s in this string. Returns -1 if
not matched.
indexOf(s, fromIndex) Returns the index of the first occurrence of string s in this string after
fromIndex. Returns -1 if not matched.
lastIndexOf(ch) Returns the index of the last occurrence of ch in the string. Returns -1 if not
matched.
lastIndexOf(ch, Returns the index of the last occurrence of ch before fromIndex in this
fromIndex) string. Returns -1 if not matched.
lastIndexOf(s) Returns the index of the last occurrence of string s. Returns -1 if not matched.
lastIndexOf(s, Returns the index of the last occurrence of string s before fromIndex.
fromIndex) Returns -1 if not matched.
30
Finding a Character or a Substring in a
String
int k = s.indexOf(' ');
String firstName = s.substring(0, k);
String lastName = s.substring(k + 1);
31
public class Main {
Example public static void main(String[] args) {
String mes="welcome to java";
System.out.println(mes.substring(11));
System.out.println(mes.substring(0,11));
int k = mes.indexOf(' ');
String first = mes.substring(0, k);
String last = mes.substring(k + 1);
System.out.println("First ="+first);
System.out.println("last ="+last);
}
}
Conversion between Strings and
Numbers
public class Main {
public static void main(String[] args) {
String intString ="5";
int intValue = Integer.parseInt(intString);
String doubleString ="5.0";
double doubleValue = Double.parseDouble(doubleString);
System.out.println("intValue= "+intValue);
System.out.println("doubleValue= "+doubleValue);
}
}
33
public class Main {
public static void main(String[] args) {
Example String str1 = “Cat";
String str2 = “Cat";
String str3 = new String(str1);
String str4 = “CAT";
System.out.println("str1.equals(str2): "+str1.equals(str2));
System.out.println("str1==str2 : "+(str1==str2));
System.out.println("str1==str3 : "+(str1==str3));
System.out.println("str1.equalsIgnoreCase(str4) : "+str1.equalsIgnoreCase(str4));
System.out.println("str1.compareTo(str2) : "+str1.compareTo(str2));
System.out.println("str1.compareTo(str3) : "+str1.compareTo(str4));
}
}
4
String Pool
• String str1 = “Cat";
String str2 = “Cat";
String str3 = new String(str1);
• So, the question here is why str1==str2 is true while str1==str3 is false
• This is because String Pool in java Heap memory (part of JVM)
• String pool helps in saving a lot of space for Java Runtime although it takes
more time to create the String. When we use double quotes to create a
String, it first looks for a String with the same value in the String pool, if
found it just returns the reference else it creates a new String in the pool
and then returns the reference.
• However, using new operator, we force String class to create a new String
object in heap space.
String Pool
Java Strings are immutable
• The string is immutable means
once we created a string variable
we cannot modify it.
• Objects in Java are created in heap
memory. So String objects are also
created in the heap. But here the
thing is, there is a special memory
area to store strings in Java,
known as String Constant Pool.
Assume we create a String variable
as below.
• String str1 = "Java";
• This is how it is stored inside the
memory.
Java Strings are immutable
• References are stored in a memory area called stack. So “str ”will be
placed in the stack and “Java” will be stored in the string constant
pool. And str1 refers to the string object Java.
• Now, what will happen if we add the str2 variable with the same
value “Java”. Will it create another object as “Java” to refer to the
str2?
StringBuffer StringBuilder
Thread Safe Not Thread Safe
Synchronized Not Synchronized
Since Java 1.0 Since Java 1.5
Slower Faster
Operators
• Arithmetic operators
Operators
• Relational operators
Operators
Logical operators
Example:
• The variable eitherPositive is assigned the value true,
because a > 0 is true and therefore the whole expression is
true (even though b > 0 is false).
• The variable bothNegative is assigned the value false
because a < 0 is false, and
• therefore the whole expression is false. Even though b < 0
is true.
49
Augmented Assignment Operators
50
Increment and
Decrement Operators
51
Conditional processing
• The flow control structures determine the way in which a Java program is executed, allowing different
segments of code to be executed under different circumstances.
• If the logical_expression within the parentheses evaluates to true, then any statements in the following
code block are executed. If the logical_expression is false, then any statements in the body of the if
statement are not executed.
Example:
52
Conditional processing
if (number % 2 == 0) Equivalent
even = true; boolean even
else = number % 2 == 0;
even = false;
(a) (b)
Equivalent if (even)
if (even == true)
System.out.println( System.out.println(
"It is even."); "It is even.");
(a) (b)
53
Multiple Alternative if Statements
(a) (b)
54
Multiple Alternative if Statements
The else clause matches the most recent if clause in the same block.
55
Conditional Operators
if (x > 0)
y=1
else
y = -1;
is equivalent to
y = (x > 0) ? 1 : -1;
(boolean-expression) ? expression1 : expression2
56
Conditional Operator
public class Main {
public static void main(String[] args) {
int num=5;
if (num % 2 == 0)
System.out.println(num + " is even");
else
System.out.println(num + " is odd");
System.out.println((num % 2 == 0)? num + " is even" : num + " is odd");
}
}
57
switch Statements
switch (status) {
case 0: stmat;
break;
case 1: stmat;
break;
case 2: stmat;
break;
case 3: stmat;
break;
default: System.out.println("Errors: invalid status");
System.exit(1);
}
58
switch Statement Rules
The switch expression must yield a value of
char, byte, short, or int type It also works switch (switch-expression) {
with enumerated types (discussed in Enum
Types), the String class, and a few special case value1: statement(s)1;
classes that wrap certain primitive types: break;
Character, Byte, Short, and Integer and must
always be enclosed in parentheses. case value2: statement(s)2;
break;
…
The value1, ..., and valueN must have the same case valueN: statement(s)N;
data type as the value of the switch expression. break;
The resulting statements in the case statement are
default: statement(s)-for-default;
executed when the value in the case statement
matches the value of the switch expression. Note }
that value1, ..., and valueN are constant
expressions, meaning that they cannot contain
variables in the expression, such as 1 + x.
59
switch Statement Rules
60
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Example
System.out.println("Enter Daya : ");
Scanner inp=new Scanner(System.in);
int day= inp.nextInt();
switch (day) {
case 1:System.out.println("1");
case 2:System.out.println("2");
case 3:System.out.println("3");
case 4:System.out.println("4");
case 5: System.out.println("Weekday"); break;
case 0:System.out.println("0");
case 6: System.out.println("Weekend");
}
}
}
Repetitive processing
• Java allow sections of code to be executed repeatedly while some
condition is satisfied → iteration!
Example:
62
Repetitive processing
Examples:
63
Example
public class Main {
public static void main(String[] args) {
int sum = 0;
int n = 1000;
for (int i = 1; i <= n; ++i) { Sum = 500500
sum += i;
}
System.out.println("Sum = " + sum);
}
}
Repetitive processing
• The initial action in a for loop can be a list of zero or more comma-
separated expressions.
• The action-after-each-iteration in a for loop can be a list of zero or
more comma-separated statements.
• But the control statement in for loop is only one statement
• 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}
65
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
for(int i=1;i<10;System.out.println(i++));
}
for(int i=0,j=0;(i+j<5);i++,j++){
} System.out.println("i= "+i+" and j= "+j);
}
}
}
Repetitive processing
• If the loop-continuation condition in a for loop is omitted, it is
implicitly true.
• Thus the statement given below in (a), which is an infinite loop, is
correct. Nevertheless, it is better to use the equivalent loop in (b) to
avoid confusion:
67
import java.util.Scanner;
public class Main {
public static void main(String[] args) { Example
int sum = 0;
Scanner input = new Scanner(System.in); Enter a number
System.out.println("Enter a number"); 25
int number = input.nextInt(); Enter a number
9
while (number >= 0) { Enter a number
sum += number; 5
System.out.println("Enter a number"); Enter a number
-3
number = input.nextInt(); Sum = 39
}
System.out.println("Sum = " + sum);
input.close();
}
}
Example
public class Main {
public static void main(String[] args) {
int i = 1, n = 5;
do { 1
System.out.println(i); 2
3
4
i++; 5
Syntax Errors
• Detected by the compiler
Runtime Errors
• Causes the program to abort
Logic Errors
• Produces incorrect result
70
Syntax Errors
71
Runtime Errors
Division on zero
72
Logic Errors
73
Common Error : Undeclared/Uninitialized
Variables and Unused Variables
74
Common Error : Integer Overflow
75
Common Error : Round-off Errors
public class Main {
public static void main(String[] args) {
System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);
System.out.println(1.0 - 0.9);
}
}
76
Common Error : Round-off Errors
• A round-off error, also called a rounding error, is the difference
between the calculated approximation of a number and its exact
mathematical value.
• For example, 1/3 is approximately 0.333 if you keep three decimal
places, and is 0.3333333 if you keep seven decimal places.
• Since the number of digits that can be stored in a variable is limited,
round-off errors are inevitable.
• Calculations involving floating-point numbers are approximated
because these numbers are not stored with complete accuracy.
Common Error : Unintended Integer
Division
int number1 = 1; int number1 = 1;
int number2 = 2; int number2 = 2;
double average = (number1 + number2) / 2; double average = (number1 + number2) / 2.0;
System.out.println(average); System.out.println(average);
(a) (b)
• Java uses the same divide operator, namely /, to perform both integer and
floating-point division.
• When two operands are integers, the / operator performs an integer division.
The result of the operation is an integer. The fractional part is dropped.
• To force two integers to perform a floating-point division, make one of the
integers into a floating-point number.
78
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);
}
• This mistake is hard to find, because it is not a compilation error or a runtime
error, it is a logic error.
• This error often occurs when you use the next-line block style.
79
public class Main {
public static void main(String[] args) {
Common Errors
double radius=-1,area,PI= 3.14;
if (radius >= 0);
{
area = radius*radius*PI;
System.out.println("The area for the circle of radius " + radius + " is " + area);
} }
}
Common Errors
Adding a semicolon at the end of the for clause before the loop body is
a common mistake, as shown below (similar to previous example:
Logic
Error
81
public class Main { Common Errors
public static void main(String[] args) {
int i=0;
for (i=0; i<10; i++);
{
System.out.println("i is " + i);
}
}
}
83
Common Pitfall : Redundant Input
Objects
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int v1 = input.nextInt();
Scanner input1 = new Scanner(System.in);
System.out.print("Enter a double value: ");
double v2 = input1.nextDouble();
The code is not good. It creates two input objects unnecessarily
and may lead to some errors. 84
Thanks
MCQ Questions
• Solve Ch 1,2,3,4,5
• https://media.pearsoncmg.com/ph/esm/ecs_liang_ijp_12/cw/#selfte
st
References
• Java: How To Program, Early Objects, 11th edition
• Cay S. Horstmann, Big Java: Late Objects
• Setup IntelliJ IDEA (2021) for JavaFX & SceneBuilder and Create Your First JavaFX Application –
YouTube
• Introduction to Java Programming and Data Structures, Comprehensive Version 12th Edition, by
Y. Liang (Author), Y. Daniel Liang
• Java documentation https://docs.oracle.com/javase
• https://www.youtube.com/watch?v=LTgClBqDank&feature=youtu.be
• https://medium.com/java-for-beginners/understanding-java-virtual-machine-jvm-architecture-
e68d1c611026
• https://medium.com/@mohamedathan3/architecture-of-java-virtual-machine-c628c6b034f4
References
• https://medium.com/javarevisited/how-java-code-compiled-and-run-e4702fb83ffa
• https://simplesnippets.tech/execution-process-of-java-program-in-detail-working-of-just-it-
time-compiler-jit-in-detail/
• JVM Architecture - MindScripts Tech
• compilation - Is Java a Compiled or an Interpreted programming language ? - Stack Overflow
• What is Java String Pool? | DigitalOcean
• https://blog.devgenius.io/java-string-is-immutable-what-does-it-actually-mean-6c7e9194a007
• StringBuffer class in Java – GeeksforGeeks
• StringBuilder Class in Java with Examples – GeeksforGeeks
• String vs StringBuffer vs StringBuilder | DigitalOcean
Advanced Programming Language
Dr. Ahmed Hesham Mostafa
Dr. Mohamed Atia
Lecture 2 – Java Basics
Single Array
Methods
2
Defining Methods
return result;
}
3
Defining Methods
4
Method Signature
Method signature is the combination of the method name and the parameter list.
5
Formal Parameters
6
Actual Parameters
When a method is invoked, you pass a value to the parameter. This value is referred
to as actual parameter or argument.
7
Return Value Type
A method may return a value. The returnValueType is the data type of the value the
method returns. If the method does not return a value, the returnValueType is the
keyword void. For example, the returnValueType in the main method is void.
8
Call Stacks
9
Caution
A return statement is required for a value-returning method. The method shown
below in (a) is logically correct, but it has a compilation error because the Java
compiler thinks it possible that this method does not return any value.
To fix this problem, delete if (n < 0) in (a), so that the compiler will see a return
statement to be reached regardless of how the if statement is evaluated.
10
Single Arrays
Arrays
• way of creating an array is as follows:
int[] holder = new int[5];
Here, we have only stated that there should be room for five integers to be stored. We can
initialize these elements (they will default to the value 0) using assignment to individual
locations:
holder[0]= 1;
holder[1]= 1;
holder[2]= 1;
holder[3]= 1;
holder[4]= 1;
• This is equivalent to the following:
int[] myArray = {1,1,1,1,1};
12
Arrays
13
Arrays
• Note that length is an instance variable associated with arrays, while length() is a
method associated with strings.
14
Default Values
• When an array is created, its elements are assigned the
default value of :
• 0 for the numeric primitive data types
• '\u0000' for char types
• false for boolean types.
15
Indexed Variables
• The array elements are accessed through the index.
• The array indices are 0-based, i.e., it starts from 0 to
arrayRefVar.length-1.
• Each element in the array is represented using the following
syntax, known as an indexed variable: arrayRefVar[index];
16
Declaring, creating, initializing Using
the Shorthand Notation
17
Caution
•Using the shorthand notation, you have to
declare, create, and initialize the array all in
one statement.
• Splitting it would cause a syntax error. For
example, the following is wrong:
double[] myList;
18
Initializing arrays with input values
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
double[] myList = new double[3]; Enter 3 values:
Scanner input = new Scanner(System.in); 5
System.out.println("Enter " + myList.length + " values: "); 6
for (int i = 0; i < myList.length; i++) { 9
myList[i] = input.nextDouble(); mylist[0]=5.0
} mylist[1]=6.0
for (int i = 0; i < myList.length; i++) { mylist[2]=9.0
System.out.println("mylist["+i+"]="+myList[i]);
}
}
}
19
Initializing arrays with random values
public class Main {
public static void main(String[] args) {
mylist[0]=99
int[] myList = new int[3]; mylist[1]=71
for (int i = 0; i < myList.length; i++) { mylist[2]=71
myList[i] = (int)(Math.random() * 100);
}
for (int i = 0; i < myList.length; i++) {
System.out.println("mylist["+i+"]="+myList[i]);
}
}
}
20
Note : The random Method
• Generates a random double value greater than or equal to 0.0 and less than 1.0
• (0 <= Math.random() < 1.0).
Examples:
In general,
21
Shifting Elements
public class Main {
public static void main(String[] args) {
int[] myList = new int[4];
for (int i = 0; i < myList.length; i++) { Before Shifting:
myList[i] = (int)(Math.random() * 100);
} mylist[0]=71
System.out.println("Before Shifting:"); mylist[1]=88
for (int i = 0; i < myList.length; i++) { mylist[2]=21
System.out.println("mylist["+i+"]="+myList[i]);
} mylist[3]=11
int temp=myList[0];
for (int i = 1; i < myList.length; i++) { After Shifting:
myList[i-1]=myList[i];
} mylist[0]=88
myList[myList.length-1]=temp; mylist[1]=21
System.out.println("After Shifting:"); mylist[2]=11
for (int i = 0; i < myList.length; i++) {
System.out.println("mylist["+i+"]="+myList[i]); mylist[3]=71
}
}
} 22
Enhanced for Loop (for-each
loop)
• JDK 1.5 introduced a new for loop that enables you to traverse the complete
array sequentially without using an index variable. For example, the following
code displays all elements in the array myList:
• You still have to use an index variable if you wish to traverse the array in a
different order or change the elements in the array.
23
public class Main { Enhanced for
Loop (for-each
public static void main(String[] args) {
int[] marks = { 125, 132, 95, 116, 110 };
int highest_marks = maximum(marks);
System.out.println("The highest score is " + highest_marks); loop)
}
public static int maximum(int[] numbers)
{
int maxSoFar = numbers[0];
// for each loop The highest score is 132
for (int num : numbers)
{
if (num > maxSoFar)
{
maxSoFar = num;
}
}
return maxSoFar;
}}
Copying Arrays
• Often, in a program, you need to duplicate an array or a part of an
array. In such cases you could attempt to use the assignment
statement (=), as follows: list2 = list1;
25
Copying Arrays
• Using a loop:
int[] sourceArray = {2, 3, 1, 5, 10};
int[] targetArray = new int[sourceArray.length];
26
The arraycopy Utility
arraycopy(sourceArray, src_pos, targetArray,
tar_pos, length);
Example:
System.arraycopy(sourceArray, 0, targetArray, 0,
sourceArray.length);
27
public class Main {
public static void main(String[] args) {
int[] sourceArray = {2, 3, 1, 5, 10};
int[] targetArray = {8,9,11,13}; source array
int[] temparray=new int[sourceArray.length]; 8 9 11 13
sourceArray=targetArray; target array
System.out.println("source array"); 8 9 11 13
for (int i:sourceArray) { address sourceArray = [I@1d81eb93
System.out.print(i+" "); address targetArray = [I@1d81eb93
} address temparray = [I@7291c18f
System.arraycopy(sourceArray, 0, temparray, 0, sourceArray.length);
System.out.println();
System.out.println("target array");
for (int i:sourceArray) {
System.out.print(i+" ");
}
System.out.println();
System.out.println("address sourceArray = "+sourceArray);
System.out.println("address targetArray = "+targetArray);
System.out.println("address temparray = "+temparray);
}
}
Passing Arrays to Methods
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
Anonymous array
29
Anonymous Array
• The statement
printArray(new int[]{3, 1, 2, 6, 4, 2});
• creates an array using the following syntax:
new dataType[]{literal0, literal1, ..., literalk};
• There is no explicit reference variable for the array. Such
array is called an anonymous array.
30
Pass By Value
• 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.
• For a parameter of a primitive type value, the actual value is passed.
Changing the value of the local parameter inside the method does not
affect the value of the variable outside the method.
• For a parameter of an array type, the value of the parameter contains a
reference to an array; this reference is passed to the method. Any changes
to the array that occur inside the method body will affect the original array
that was passed as the argument.
31
Simple Example
public class Main {
public static void main(String[] args) {
32
Returning an Array from a Method
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
return result;
}
33
Variable-Length Arguments
You can pass a variable number of arguments of the same type to a
method.
public class Main {
public static void printMax(double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return; The max value is 56.5
} The max value is 3.0
double result = numbers[0];
for (int i = 1; i < numbers.length; i++)
if (numbers[i] > result)
result = numbers[i];
System.out.println("The max value is " + result);
}
public static void main(String[] args) {
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3}); }
}
34
Linear Search
• The linear search approach compares the key element, key,
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.
35
Linear Search Implementation
public class Main {
public static int linearSearch(int[] list, int key) {
for (int i = 0; i < list.length; i++)
if (key == list[i])
return i;
return -1;
}
public static void main(String[] args) {
int[] list = {1, 4, 4, 2, 5, -3, 6, 2};
System.out.println(linearSearch(list, 4)); 1
System.out.println(linearSearch(list, -4)); -1
System.out.println(linearSearch(list, -3)); 5
}
}
36
The Arrays.sort Method
Since sorting is frequently used in programming, Java provides several overloaded sort
methods for sorting an array of int, double, char, short, long, and float in the java.util.Arrays
class. For example, the following code sorts an array of numbers and an array of characters.
37
Main Method Is Just a Regular Method
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:
38
class B {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
}
} New York
Boston
public class Main { Atlanta
public static void main(String[] args) {
String[] strings = {"New York",
"Boston", "Atlanta"};
B.main(strings);
}
}
Two-dimensional Arrays
Declare/Create Two-dimensional Arrays
// Declare array ref var
dataType[][] refVar;
// Alternative syntax
dataType refVar[][] = new dataType[10][10];
41
Declaring Variables of Two-
dimensional Arrays and Creating
Two-dimensional Arrays
42
Two-dimensional Array Illustration
matrix.length? 5 array.length? 4
matrix[0].length? 5 array[0].length? 3
43
Declaring, Creating, and Initializing Using
Shorthand Notations
int[][] array = {
int[][] array = new int[4][3];
{1, 2, 3}, array[0][0] = 1; array[0][1] = 2; array[0][2] = 3;
{4, 5, 6}, Same as array[1][0] = 4; array[1][1] = 5; array[1][2] = 6;
{7, 8, 9}, array[2][0] = 7; array[2][1] = 8; array[2][2] = 9;
{10, 11, 12} array[3][0] = 10; array[3][1] = 11; array[3][2] = 12;
};
44
Lengths of Two-dimensional Arrays
45
Lengths of Two-dimensional Arrays,
cont.
array[4].length ArrayIndexOutOfBoundsException
46
Ragged Arrays
Each row in a two-dimensional array is itself an array. So, the rows can
have different lengths. Such an array is known as a ragged array. For
example,
int[][] triangleArray = {
{1, 2, 3, 4, 5},
triangleArray.length is 5
{2, 3, 4, 5}, triangleArray[0].length is 5
{3, 4, 5}, triangleArray[1].length is 4
triangleArray[2].length is 3
{4, 5}, triangleArray[3].length is 2
{5} triangleArray[4].length is 1
};
47
Ragged Arrays, cont.
48
Printing arrays
public class Main {
public static void main(String[] args) {
int[][] triangleArray = {
{1, 2, 3, 4, 5}, 12345
2345
{2, 3, 4, 5},
345
{3, 4, 5}, 45
{4, 5}, 5
{5}
};
for (int row = 0; row < triangleArray.length; row++) {
for (int column = 0; column < triangleArray[row].length; column++) {
System.out.print(triangleArray[row][column] + " ");
}
System.out.println();
}
}
}
49
Summing all elements
public class Main {
public static void main(String[] args) {
int[][] triangleArray = {
{1, 2, 3, 4, 5},
{2, 3, 4, 5},
{3, 4, 5},
{4, 5}, total = 55
{5}
};
int total = 0;
for (int row = 0; row < triangleArray.length; row++) {
for (int column = 0; column < triangleArray[row].length; column++) {
total += triangleArray[row][column];
}
}
System.out.println("total = "+total);
}
} 50
Problem: Grading Multiple-Choice
Test
Students’ answer Objective: write a
program that grades
multiple-choice test.
51
public class Main {
public static void main(String[] args) {
// Students' answers to the questions
Problem: Grading Multiple-Choice
char[][] answers = {
{'A', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
Test
{'D', 'B', 'A', 'B', 'C', 'A', 'E', 'E', 'A', 'D'},
{'E', 'D', 'D', 'A', 'C', 'B', 'E', 'E', 'A', 'D'},
{'C', 'B', 'A', 'E', 'D', 'C', 'E', 'E', 'A', 'D'},
{'A', 'B', 'D', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
{'B', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
{'B', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D'},
Student 0's correct count is 7
{'E', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D'}};
Student 1's correct count is 6
// Key to the questions
Student 2's correct count is 5
char[] keys = {'D', 'B', 'D', 'C', 'C', 'D', 'A', 'E', 'A', 'D'};
Student 3's correct count is 4
// Grade all answers
Student 4's correct count is 8
for (int i = 0; i < answers.length; i++) {
Student 5's correct count is 7
// Grade one student
Student 6's correct count is 7
int correctCount = 0;
Student 7's correct count is 7
for (int j = 0; j < answers[i].length; j++) {
if (answers[i][j] == keys[j])
correctCount++;
}
System.out.println("Student " + i + "'s correct count is " +correctCount);
} }}
Problem: Finding Two Points
Nearest to Each Other
PassTwoDimensionalArray
PassTwoDimensionalArray
53
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the number of points: "); // Display result
int numberOfPoints = input.nextInt();
System.out.println("The closest two points are " +
// Create an array to store points
double[][] points = new double[numberOfPoints][2]; "(" + points[p1][0] + ", " + points[p1][1] + ") and (" +
System.out.print("Enter " + numberOfPoints + " points: "); points[p2][0] + ", " + points[p2][1] + ")");
for (int i = 0; i < points.length; i++) { }
points[i][0] = input.nextDouble();
points[i][1] = input.nextDouble(); public static double distance(
} double x1, double y1, double x2, double y2) {
// p1 and p2 are the indices in the points array return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
int p1 = 0, p2 = 1; // Initial two points
}
double shortestDistance = distance(points[p1][0], points[p1][1],
points[p2][0], points[p2][1]); // Initialize shortestDistance }
// Compute distance for every two points Enter the number of points: 4
for (int i = 0; i < points.length; i++) { Enter 4 points:
for (int j = i + 1; j < points.length; j++) { 12
double distance = distance(points[i][0], points[i][1], 22
points[j][0], points[j][1]); // Find distance
35
if (shortestDistance > distance) {
p1 = i; // Update p1 21
p2 = j; // Update p2 The closest two points are (1.0, 2.0) and (2.0, 2.0)
shortestDistance = distance; // Update shortestDistance
} } }
Multidimensional Arrays
Multidimensional Arrays
• Occasionally, you will need to represent n-dimensional data
structures. In Java, you can create n-dimensional arrays for any
integer n.
• The way to declare two-dimensional array variables and create two-
dimensional arrays can be generalized to declare n-dimensional array
variables and create n-dimensional arrays for n >= 3.
56
Multidimensional Arrays
double[][][] scores = {
{{7.5, 20.5}, {9.0, 22.5}, {15, 33.5}, {13, 21.5}, {15, 2.5}},
{{4.5, 21.5}, {9.0, 22.5}, {15, 34.5}, {12, 20.5}, {14, 9.5}},
{{6.5, 30.5}, {9.4, 10.5}, {11, 33.5}, {11, 23.5}, {10, 2.5}},
{{6.5, 23.5}, {9.4, 32.5}, {13, 34.5}, {11, 20.5}, {16, 7.5}},
{{8.5, 26.5}, {9.4, 52.5}, {13, 36.5}, {13, 24.5}, {16, 2.5}},
{{9.5, 20.5}, {9.4, 42.5}, {13, 31.5}, {12, 20.5}, {16, 6.5}}
};
scores[ i ] [ j ] [ k ]
57
Problem: Calculating Total Scores
• Objective: write a program that calculates the total score for students in a class.
Suppose the scores are stored in a three-dimensional array named scores.
• The first index in scores refers to a student, the second refers to an exam, and
the third refers to the part of the exam.
• Suppose there are 7 students, 5 exams, and each exam has two parts--the
multiple-choice part and the programming part.
• So, scores[i][j][0] represents the score on the multiple-choice part for the i’s
student on the j’s exam.
• Your program displays the total score for each student.
58
public class Main {
public static void main(String[] args) {
double[][][] scores = {
{{7.5, 20.5}, {9.0, 22.5}, {15, 33.5}, {13, 21.5}, {15, 2.5}},
{{4.5, 21.5}, {9.0, 22.5}, {15, 34.5}, {12, 20.5}, {14, 9.5}},
{{6.5, 30.5}, {9.4, 10.5}, {11, 33.5}, {11, 23.5}, {10, 2.5}},
{{6.5, 23.5}, {9.4, 32.5}, {13, 34.5}, {11, 20.5}, {16, 7.5}},
{{8.5, 26.5}, {9.4, 52.5}, {13, 36.5}, {13, 24.5}, {16, 2.5}}, Student 0's score is 160.0
Student 1's score is 163.0
{{9.5, 20.5}, {9.4, 42.5}, {13, 31.5}, {12, 20.5}, {16, 6.5}},
Student 2's score is 148.4
{{1.5, 29.5}, {6.4, 22.5}, {14, 30.5}, {10, 30.5}, {16, 6.0}}}; Student 3's score is 174.4
// Calculate and display total score for each student Student 4's score is 202.4
for (int i = 0; i < scores.length; i++) { Student 5's score is 181.4
double totalScore = 0; Student 6's score is 166.9
for (int j = 0; j < scores[i].length; j++)
for (int k = 0; k < scores[i][j].length; k++)
totalScore += scores[i][j][k];
Data Fields:
radius is _______
Methods:
getArea
class header
state
constructors
methods
Example (cont.)
2.Construct an object
3.Store an object reference.
After execution →
The keyword null represents a reference that does not point at any object.
Reference variables and assignment
• If we write:
Circle() {
}
Circle(double newRadius) {
radius = newRadius;
}
Constructors, cont.
A constructor with no parameters is referred to as a no-arg 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.
Constructors, cont.
• Remember that a constructor cannot be abstract, final, synchronized,
and static. We cannot override a constructor.
• There are two types of constructor in Java:
• Default Constructor (also known as a no-argument constructor)
• Parameterized Constructor
Creating Objects Using Constructors
new ClassName();
Example:
new Circle();
new Circle(5.0);
Default Constructor
• A class may be defined without constructors. In this case, a no-arg
constructor with an empty body is implicitly defined in the class. This
constructor, called a default constructor, is provided automatically
only if no constructors are explicitly defined in the class.
ClassName objectRefVar;
Example:
Circle myCircle;
Declaring/Creating Objects
in a Single Step
ClassName objectRefVar = new ClassName();
radius: 5.0
: Circle
Change radius in radius: 100.0
yourCircle
Caution
• Recall that you use
Math.methodName(arguments) (e.g., Math.pow(3, 2.5))
• to invoke a method in the Math class. Can you invoke getArea() using
SimpleCircle.getArea()? The answer is no. All the methods used before this
chapter are static methods, which are defined using the static keyword.
• However, getArea() is non-static. It must be invoked from an object using
objectRefVar.methodName(arguments) (e.g., myCircle.getArea()).
• More explanations will be given in the section on “Static Variables, Constants, and
Methods.”
Reference Data Fields
• The data fields can be of reference types. For example, the following
Student class contains a data field name of the String type.
public class Student {
String name; // name has default value null
int age; // age has default value 0
boolean isScienceMajor; // isScienceMajor has default value false
char gender; // c has default value '\u0000'
}
Default Value for a Data Field
• If a data field of a reference type does not reference any object, the
data field holds a special literal value, null.
• 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 Value for a Data Field
public class Test {
public static void main(String[] args) {
Student student = new Student();
System.out.println("name? " + student.name);
System.out.println("age? " + student.age);
System.out.println("isScienceMajor? " +
student.isScienceMajor);
System.out.println("gender? " + student.gender);
}
} name? null
age? 0
isScienceMajor? false
gender?
Default Value for a Data Field
• 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);
}
}
Compile error: variable not initialized
Differences between Variables of
Primitive Data Types and Object Types
radius = 1
Copying Variables of Primitive Data Types and
Object Types
Object type assignment c1 = c2
c1 c1
Before: After:
i 1 i 2 c2 c2
❑ private
The data or methods can be accessed only by the declaring class.
The get and set methods are used to read and modify private
properties.
Visibility Modifiers and
Accessor/Mutator Methods
• The private modifier restricts access to within a class, the default
modifier restricts access to within a package, and the public modifier
enables unrestricted access.
Visibility Modifiers and
Accessor/Mutator Methods
• The default modifier on a class restricts access to within a package,
and the public modifier enables unrestricted access.
NOTE
• An object cannot access its private members, as shown in (b). It is OK,
however, if the object is declared in its own class, as shown in (a).
Why Data Fields Should Be private?
• To protect data.
• Data Encapsulation
Example of
Data Field Encapsulation
Circle
The - sign indicates
private modifier -radius: double The radius of this circle (default: 1.0).
-numberOfObjects: int The number of circle objects created.
Radius is 6.0
n is 5
Passing Objects to Methods, cont.
Array of Objects
• Circle[] circleArray = new Circle[10];
• This is allowed →
public class three {
private int a,b,c;
The this Keyword public three(int a,int b,int c){
this.a=a;
this.b=b;
❑The this keyword is the name of a reference this.c=c;
that refers to an object itself. One common }
public three(){
use of the this keyword is reference a class’s
this(0,0,0);
hidden data fields. }
public three(int a){
❑Another common use of the this keyword to this(a,0,0);
enable a constructor to invoke another }
public three(int a,int b){
constructor of the same class. (Calling
this(a,b,0);
Overloaded Constructor) }
}
Class Abstraction and Encapsulation
Class abstraction means to separate class implementation
from the use of the class. The creator of the class
provides a description of the class and let the user know
how the class can be used. The user of the class does not
need to know how the class is implemented. The detail of
implementation is encapsulated and hidden from the
user.
53
Designing the Loan Class
Loan
-annualInterestRate: double The annual interest rate of the loan (default: 2.5).
-numberOfYears: int The number of years for the loan (default: 1)
-loanAmount: double The loan amount (default: 1000).
-loanDate: Date The date this loan was created.
Loan TestLoanClass
Loan TestLoanClass
54
public class Loan {
private double annualInterestRate;
private int numberOfYears; public double getLoanAmount() {
private double loanAmount; return loanAmount;
private java.util.Date loanDate;
}
/** No-arg constructor */ public void setLoanAmount(double loanAmount) {
public Loan() { this.loanAmount = loanAmount;
this(2.5, 1, 1000); }
} public double getMonthlyPayment() {
public Loan(double annualInterestRate, int numberOfYears, double monthlyInterestRate = annualInterestRate / 1200;
double loanAmount) { double monthlyPayment = loanAmount * monthlyInterestRate / (1 -
this.annualInterestRate = annualInterestRate;
(1 / Math.pow(1 + monthlyInterestRate, numberOfYears * 12)));
this.numberOfYears = numberOfYears;
this.loanAmount = loanAmount; return monthlyPayment;
loanDate = new java.util.Date(); }
} public double getTotalPayment() {
public double getAnnualInterestRate() { double totalPayment = getMonthlyPayment() * numberOfYears * 12;
return annualInterestRate; return totalPayment;
} }
public void setAnnualInterestRate(double annualInterestRate) {
public java.util.Date getLoanDate() {
this.annualInterestRate = annualInterestRate;
} return loanDate;
}
public int getNumberOfYears() { }
return numberOfYears;
}
public void setNumberOfYears(int numberOfYears) {
this.numberOfYears = numberOfYears;
}
Enter annual interest rate, for example, 8.25: 22
import java.util.Scanner; Enter number of years as an integer: 5
Enter loan amount, for example, 120000.95: 120000
public class Main { The loan was created on Tue Nov 08 19:00:49 EET 2022
public static void main(String[] args) { The monthly payment is 3314.27
Scanner input = new Scanner(System.in); The total payment is 198856.17
System.out.print(
"Enter annual interest rate, for example, 8.25: ");
double annualInterestRate = input.nextDouble();
System.out.print("Enter number of years as an integer: ");
int numberOfYears = input.nextInt();
System.out.print("Enter loan amount, for example, 120000.95: ");
double loanAmount = input.nextDouble();
Loan loan =
new Loan(annualInterestRate, numberOfYears, loanAmount);
System.out.printf("The loan was created on %s\n" +
"The monthly payment is %.2f\nThe total payment is %.2f\n",
loan.getLoanDate().toString(), loan.getMonthlyPayment(),
loan.getTotalPayment());
}
}
Example: The Course Class
Course
-courseName: String The name of the course.
-students: String[] An array to store the students for the course.
-numberOfStudents: int The number of students (default: 0).
+Course(courseName: String) Creates a course with the specified name.
+getCourseName(): String Returns the course name.
+addStudent(student: String): void Adds a new student to the course.
+dropStudent(student: String): void Drops a student from the course.
+getStudents(): String[] Returns the students in the course.
+getNumberOfStudents(): int Returns the number of students in the course.
Course TestCourse
Course TestCourse
57
public class Course {
private String courseName;
private String[] students = new String[100];
private int numberOfStudents; public void dropStudent(String student) {
System.out.println();
System.out.print("Number of students in course2: "
+ course2.getNumberOfStudents());
}
}
Example: The StackOfIntegers
Class
StackOfIntegers
-elements: int[] An array to store integers in the stack.
-size: int The number of integers in the stack.
+StackOfIntegers() Constructs an empty stack with a default capacity of 16.
+StackOfIntegers(capacity: int) Constructs an empty stack with a specified capacity.
+empty(): boolean Returns true if the stack is empty.
+peek(): int Returns the integer at the top of the stack without
removing it from the stack.
+push(value: int): int Stores an integer into the top of the stack.
+pop(): int Removes the integer at the top of the stack and returns it.
+getSize(): int Returns the number of elements in the stack.
TestStackOfIntegers
TestStackOfIntegers
60
public class StackOfIntegers {
private int[] elements; public int pop() {
private int size; return elements[--size];
private int DEFAULT_CAPACITY = 16; }
public StackOfIntegers(int capacity) { public int peek() {
elements = new int[capacity];
return elements[size - 1];
}
public StackOfIntegers() { }
elements = new int[DEFAULT_CAPACITY]; public boolean empty() {
} return size == 0;
public void push(int value) { }
if (size >= elements.length) { public int getSize() {
int[] temp = new int[elements.length * 2]; return size;
System.arraycopy(elements, 0, temp, 0, elements.length); }
elements = temp; }
}
elements[size++] = value;
}
public class Main {
public static void main(String[] args) {
StackOfIntegers stack = new StackOfIntegers();
for (int i = 0; i < 10; i++)
stack.push(i); // Push i to the stack
while (!stack.empty()) // Test if stack is empty
System.out.print(stack.pop() + " "); // Remove and return from stack
}
}
9876543210
Designing the StackOfIntegers Class
63
Implementing StackOfIntegers
Class
StackOfIntegers
StackOfIntegers
64
Thanks
References
• Java: How To Program, Early Objects, 11th edition
• Cay S. Horstmann, Big Java: Late Objects
Association
Aggregation
Composition
Inheritance (Chapter 13)
2
Association
• Association: is a general binary relationship that describes an activity between
two classes.
• Association in Java is a connection or relation between two
separate classes that are set up through their objects.
• Association relationship indicates how objects know each other and
how they are using each other’s functionality.
• It can be one-to-one, one-to-many, many-to-one and many-to-many.
• This UML diagram shows that a student may take any number of courses, a
faculty member may teach at most three courses, a course may have from 5 to
60 students, and a course is taught by only one faculty member.
Association
• Each class involved in an association may specify a multiplicity, which is
placed at the side of the class to specify how many of the class’s objects are
involved in the relationship in UML.
• A multiplicity could be a number or an interval that specifies how many of
the class’s objects are involved in the relationship.
• The character * means an unlimited number of objects, and the interval
m..n indicates that the number of objects is between m and n
• For example : each student may take any number of courses, and each
course must have at least 5 and at most 60 students. Each course is taught
by only one faculty member, and a faculty member may teach from 0 to 3
courses per semester.
Association
• In Java code, you can implement associations by using data fields and
methods.
• The relation “a student takes a course” is implemented using the
addCourse method in the Student class and the addStudent method in the
Course class.
• The relation “a faculty teaches a course” is implemented using the
addCourse method in the Faculty class and the setFaculty method in the
Course class.
• The Student class may use a list to store the courses that the student is
taking, the Faculty class may use a list to store the courses that the faculty
is teaching
• Course class may use a list to store students enrolled in the course and a
data field to store the instructor who teaches the course.
Association
Object Composition
• Composition is actually a special case of the aggregation relationship.
Aggregation models has-a relationships and represents an ownership
relationship between two objects.
• The owner object is called an aggregating object and its class an
aggregating class.
• The subject object is called an aggregated object and its class an
aggregated class.
Composition Aggregation
1 1 1..3 1
Name Student Address
7
Aggregation or Composition
• We refer aggregation between two objects as composition if the existence
of the aggregated object is dependent on the aggregating object.
• In other words, if a relationship is composition, the aggregated object
cannot exist on its own
• For example, “a student has a name” is a composition relationship
between the Student class and the Name class because Name is dependent
on Student,
• “a student has an address” is an aggregation relationship between the
Student class and the Address class because an address can exist by itself.
Composition implies exclusive ownership.
• One object owns another object. When the owner object is destroyed, the
dependent object is destroyed as well. (The class (owner) who create
(construct) the object )
Class Representation
An aggregation relationship is usually represented as a
data field in the aggregating class. For example, the
relationship in Figure 10.6 can be represented as follows:
...
}
9
public class Job {
private String role;
Composition in Java
public class Person {
private long salary; Example
private int id; //composition has-a relationship
private Job job;
public String getRole() {
return role; public Person(){
} this.job=new Job();
public void setRole(String role) { job.setSalary(1000L);
this.role = role; }
} public long getSalary() {
public long getSalary() { return job.getSalary();
return salary; }
}
public void setSalary(long salary) { }
this.salary = salary;
}
public int getId() { public class TestPerson {
return id;
} public static void main(String[] args) {
public void setId(int id) { Person person = new Person();
this.id = id; long salary = person.getSalary();
} }
} }
Aggregation or Composition
Since aggregation and composition relationships are represented using
classes in similar ways, many texts don’t differentiate them and call
both compositions.
11
Aggregation Between Same Class
Aggregation may exist between objects of the same class. For example,
a person may have a supervisor.
1
Person
Supervisor
1
1
Person
Supervisor
m
13
Inheritance and Polymorphism
• Suppose you will 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.
Superclasses and Subclasses
GeometricObject
-color: String The color of the object (default: white).
-filled: boolean Indicates whether the object is filled with a color (default: false).
-dateCreated: java.util.Date The date when the object was created.
+GeometricObject() Creates a GeometricObject.
+GeometricObject(color: String, Creates a GeometricObject with the specified color and filled
filled: boolean) values.
+getColor(): String Returns the color.
+setColor(color: String): void Sets a new color.
+isFilled(): boolean Returns the filled property.
+setFilled(filled: boolean): void Sets a new filled property.
+getDateCreated(): java.util.Date Returns the dateCreated.
+toString(): String Returns a string representation of this object.
Circle Rectangle
-radius: double -width: double
+Circle() -height: double
+Circle(radius: double) +Rectangle() GeometricObject
+getRadius(): double
+setRadius(radius: double): void +getWidth(): double Circle
+getArea(): double +setWidth(width: double): void Rectangle
Rectangle rectangle = new Rectangle(2, 4); A rectangle created on Sat Nov 19 20:31:22 EET 2022
System.out.println("\nA rectangle " + rectangle.toString()); color: white and filled: false
System.out.println("The area is " + rectangle.getArea());
The area is 8.0
System.out.println("The perimeter is " +rectangle.getPerimeter());
} The perimeter is 12.0
}
Super Keyword in Java
• The super keyword in Java is a reference variable used to refer
to the immediate parent class object. It plays a crucial role in
inheritance and polymorphism, allowing subclasses to access
and utilize the properties and methods of their parent classes.
• Characteristics and Usage
• Accessing Parent Class Variables
• When a subclass and its parent class have the same variable
names, the super keyword can be used to differentiate and
access the parent class's variable. For example:
class Vehicle {
int maxSpeed = 120;
}
25
Using the Keyword 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
26
Important Points to Remember While
Using “Java Super Keyword”
• Call to super() must be the first statement in the
Derived(Student) Class constructor because if you think about it, it
makes sense that the superclass has no knowledge of any subclass,
so any initialization it needs to perform is separate from and
possibly prerequisite to any initialization performed by the subclass.
Therefore, it needs to complete its execution first.
• If a constructor does not explicitly invoke a superclass constructor,
the Java compiler automatically inserts a call to the no-argument
constructor of the superclass. If the superclass does not have a no-
argument constructor, you will get a compile-time error. The
object does have such a constructor, so if the Object is the only
superclass, there is no problem.
class HelloWorld {
public static void main(String[] args) {
Child c=new Child();
ERROR!/tmp/aXeRULLvU9/Hello }
World.java:19: error: call to super }
must be first statement in
class Parent {
constructor super(); Parent() {
System.out.println("Parent constructor");
}
}
public Faculty() {
System.out.println("(4) Faculty'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 is invoked");
}
} 31
animation
Trace Execution
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");
}
}
public Employee(String s) {
System.out.println(s);
}
}
class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}
32
animation
Trace Execution
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");
}
}
public Employee(String s) {
System.out.println(s);
}
}
class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}
33
animation
Trace Execution
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 no-
class Employee extends Person {
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 is invoked");
}
}
34
animation
Trace Execution
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 Employee(String)
class Employee extends Person { 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 is invoked");
}
}
35
animation
Trace Execution
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");
}
}
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 is invoked");
}
}
36
animation
Trace Execution
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");
}
}
public Employee(String s) {
System.out.println(s);
}
}
6. Execute println
class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}
37
animation
Trace Execution
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");
}
}
public Employee(String s) {
System.out.println(s);
}
}
7. Execute println
class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}
38
animation
Trace Execution
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");
}
}
public Employee(String s) {
System.out.println(s);
}
}
8. Execute println
class Person {
public Person() {
System.out.println("(1) Person's no-arg constructor is invoked");
}
}
39
animation
Trace Execution
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");
}
}
9. Execute println
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 is invoked");
}
}
40
The Need of Constructor Chaining
• Suppose, there are five tasks to perform. There are two ways to
perform these tasks, either implement all the tasks in a single
constructor or create separate tasks in a single constructor.
• By using the constructor chaining mechanism, we can implement
multiple tasks in a single constructor. So, whenever we face such
types of problems, we should use constructor chaining. We can make
the program more readable and understandable by using constructor
chaining.
Rules of Constructor Chaining
• An expression that uses this keyword must be the first
line of the constructor.
• Order does not matter in constructor chaining.
• There must exist at least one constructor that does not
use this
Constructor Calling form another Constructor
• The calling of the constructor can be done in two ways:
• By using this() keyword: It is used when we want to call
the current class constructor within the same class.
• By using super() keyword: It is used when we want to
call the superclass constructor from the base class.
• Note: In the same constructor block, we cannot use this() and
super() simultaneously.
Constructor Chaining Examples
Calling Current Class Constructor
• We use this() keyword if we want to call the current class constructor
within the same class. The use of this() is mandatory because JVM never
put it automatically like the super() keyword. Note that this() must be the
first line of the constructor. There must exist at least one constructor
without this() keyword.
• Syntax:
this(); or this(parameters list);
• For example:
this();
this("Javatpoint");
•
public class ConstructorChain
In the above example, we have created an {
instance of the class without passing any //default constructor
parameter. It first calls the default ConstructorChain()
constructor and the default constructor {
redirects the call to the parameterized one this("Javatpoint");
because of this(). The statements inside the System.out.println("Default constructor called.");
parameterized constructor are executed }
and return back to the default constructor. //parameterized constructor
After that, the rest of the statements in the ConstructorChain(String str)
default constructor is executed and the {
object is successfully initialized. The System.out.println("Parameterized constructor called");
following is the calling sequence of the }
constructor: //main method
public static void main(String args[])
{
//initializes the instance of example class
ConstructorChain cc = new ConstructorChain();
}
}
Calling Super Class Constructor
• Sometimes, we need to call the superclass (parent class) constructor
from the child class (derived class) in such cases, we use the super()
keyword in the derived class constructor. It is optional to write super()
because JVM automatically puts it. It should always write in the first
line. We get a syntax error if we try to call a superclass constructor in
the child class.
• Syntax:
super(); or super(Parameter List);
• super(): It calls the no-argument or default constructor of the
superclass.
• super(parameters): It invokes the superclass parameterized
constructor.
• Remember that the superclass constructor cannot be inherited in the
subclass. It can be called from the subclass constructor by using the
super keyword.
//derived class or child class
//parent class or base class class Prototype extends Demo
class Demo {
{ //derived class default constructor
//base class default constructor Prototype()
Demo() {
{ this("Java", "Python");
this(80, 90); System.out.println("Derived class default constructor called");
System.out.println("Base class default constructor called"); }
} //derived class parameterized constructor
//base class parameterized constructor Prototype(String str1, String str2)
Demo(int x, int y) {
{ super();
System.out.println("Base class parameterized constructor System.out.println("Derived class parameterized constructor
called"); called");
} } }
} public class ConstructorChaining
{
//main method
public static void main(String args[])
{
//initializes the instance of example class
Prototype my_example = new Prototype();
} }
Defining a Subclass
A subclass inherits from a superclass. You can also:
❑ Add new properties
❑ Add new methods
❑ Override the methods of the superclass
48
Calling Superclass Methods
You could rewrite the printCircle() method in the Circle class as
follows:
49
Overriding Methods in the Superclass
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.
50
Method Overloading
52
NOTE
53
Overriding vs. Overloading
public class Test { public class Test {
public static void main(String[] args) { public static void main(String[] args) {
A a = new A(); A a = new A();
a.p(10); a.p(10);
a.p(10.0); a.p(10.0);
} }
} }
class B { class B {
public void p(double i) { public void p(double i) {
System.out.println(i * 2); System.out.println(i * 2);
} }
} }
54
The Object Class and Its Methods
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.
55
The toString() method in Object
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, the at sign
(@), and a number representing this object.
56
Thanks
References
• Java: How To Program, Early Objects, 11th edition
• Cay S. Horstmann, Big Java: Late Objects
PolymorphismDemo
2
Polymorphism, Dynamic Binding and Generic Programming
public class PolymorphismDemo {
public static void main(String[] args) {
m(new GraduateStudent());
Method m takes a parameter
m(new Student());
m(new Person());
of the Object type. You can
m(new Object()); invoke it with any object.
}
public static void m(Object x) { An object of a subtype can be used wherever its
System.out.println(x.toString());
} supertype value is required. This feature is
}
known as polymorphism.
class GraduateStudent extends Student {
}
class Student extends Person { When the method m(Object x) is executed, the
public String toString() {
return "Student";
argument x’s toString method is invoked. x
} may be an instance of GraduateStudent,
}
Student, Person, or Object. Classes
class Person extends Object {
public String toString() {
GraduateStudent, Student, Person, and Object
return "Person"; have their own implementation of the toString
}
} method. Which implementation is used will be
determined dynamically by the Java Virtual
DynamicBindingDemo
Machine at runtime. This capability is known
DynamicBindingDemo as dynamic binding.
3
Generic Programming
public class PolymorphismDemo { Polymorphism allows methods to be used
public static void main(String[] args) {
m(new GraduateStudent()); generically for a wide range of object
m(new Student()); arguments. This is known as generic
m(new Person());
m(new Object()); programming. If a method’s parameter
} type is a superclass (e.g., Object), you may
public static void m(Object x) { pass an object to this method of any of
System.out.println(x.toString()); 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
class GraduateStudent extends Student {
} method, the particular implementation of
the method of the object that is invoked
class Student extends Person {
public String toString() { (e.g., toString) is determined dynamically.
return "Student";
}
}
6
Casting Objects
You have already used the casting operator to convert variables of
one primitive type to another. Casting can also be used to convert an
object of one class type to another within an inheritance hierarchy.
In the preceding section, the statement
m(new Student());
Student b = o;
Orange x = (Orange)fruit;
9
The instanceof Operator
Use the instanceof operator to test whether an object is an
instance of a class:
10
Example: Demonstrating
Polymorphism and Casting
This example creates two geometric objects: a
circle, and a rectangle, invokes the
displayGeometricObject method to display the
objects. The displayGeometricObject displays
the area and diameter if the object is a circle,
and displays area if the object is a rectangle.
CastingDemo
CastingDemo
12
public class CastingDemo {
/** Main method */
public static void main(String[] args) {
// Create and initialize two objects
Object object1 = new CircleFromSimpleGeometricObject(1);
Object object2 = new RectangleFromSimpleGeometricObject(1, 1);
// Display circle and rectangle
displayObject(object1);
displayObject(object2);
}
/** A method for displaying an object */
public static void displayObject(Object object) {
if (object instanceof CircleFromSimpleGeometricObject) {
System.out.println("The circle area is " +
((CircleFromSimpleGeometricObject)object).getArea());
System.out.println("The circle diameter is " +
((CircleFromSimpleGeometricObject)object).getDiameter());
}
else if (object instanceof
RectangleFromSimpleGeometricObject) {
System.out.println("The rectangle area is " +
((RectangleFromSimpleGeometricObject)object).getArea());
}
}
}
The equals Method
The equals() method compares the
contents of two objects. The default implementation of
the equals method in the Object class is as follows:
14
NOTE
The == comparison operator is used for
comparing two primitive data type values or for
determining whether two objects have the same
references. The equals method is intended to
test whether two objects have the same
contents, provided that the method is modified
in the defining class of the objects. The ==
operator is stronger than the equals method, in
that the == operator checks whether the two
reference variables refer to the same object.
15
The ArrayList Class
You can create an array to store objects. But the 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.
java.util.ArrayList<E>
+ArrayList() Creates an empty list.
+add(o: E) : void Appends a new element o at the end of this list.
+add(index: int, o: E) : void Adds a new element o at the specified index in this list.
+clear(): void Removes all the elements from this list.
+contains(o: Object): boolean Returns true if this list contains the element o.
+get(index: int) : E Returns the element from this list at the specified index.
+indexOf(o: Object) : int Returns the index of the first matching element in this list.
+isEmpty(): boolean Returns true if this list contains no elements.
+lastIndexOf(o: Object) : int Returns the index of the last matching element in this list.
+remove(o: Object): boolean Removes the element o from this list.
+size(): int Returns the number of elements in this list.
+remove(index: int) : boolean Removes the element at the specified index.
+set(index: int, o: E) : E Sets the element at the specified index.
16
Generic Type
ArrayList is known as a generic class with a generic type E.
You can specify a concrete type to replace E when creating
an ArrayList. For example, the following statement creates
an ArrayList and assigns its reference to variable cities. This
ArrayList object can be used to store strings.
TestArrayList
17
Differences and Similarities between Arrays
and ArrayList
Operation Array ArrayList
DistinctNumbers
DistinctNumbers
18
Array Lists from/to Arrays
Creating an ArrayList from an array of objects:
String[] array = {"red", "green", "blue"};
ArrayList<String> list = new
ArrayList<>(Arrays.asList(array));
19
Stack Animation
https://liveexample.pearsoncmg.com/dsanimation/StackeBook.html
22
The MyStack Classes
A stack to hold objects.
MyStack
MyStack
MyStack
-list: ArrayList A list to store elements.
+isEmpty(): boolean Returns true if this stack is empty.
+getSize(): int Returns the number of elements in this stack.
+peek(): Object Returns the top element in this stack.
+pop(): Object Returns and removes the top element in this stack.
+push(o: Object): void Adds a new element to the top of this stack.
+search(o: Object): int Returns the position of the first element in the stack from
the top that matches the specified element.
23
import java.util.ArrayList;
public class MyStack {
public class Main {
private ArrayList<Object> list = new ArrayList<>();
public boolean isEmpty() { public static void main(String[] args) {
return list.isEmpty(); MyStack obj=new MyStack();
} obj.push(5);
public int getSize() { obj.push("ahmed");
return list.size(); obj.push(3.7);
} obj.push('a');
public Object peek() { while(!obj.isEmpty()){
return list.get(getSize() - 1); System.out.println(obj.pop());
}
}
public Object pop() {
Object o = list.get(getSize() - 1); }
list.remove(getSize() - 1); }
return o;
} a
public void push(Object o) {
list.add(o); 3.7
}
@Override /** Override the toString in the Object class */
ahmed
public String toString() { 5
return "stack: " + list.toString();
}}
The protected Modifier
❑The protected modifier can be applied on data
and methods in a class. 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.
❑private, default, protected, public
Visibility increases
25
Accessibility Summary
public
protected -
default - -
private - - -
26
Visibility Modifiers
package p1;
public class C1 { public class C2 {
public int x; C1 o = new C1();
protected int y; can access o.x;
int z; can access o.y;
private int u; can access o.z;
cannot access o.u;
protected void m() {
} can invoke o.m();
} }
package p2;
27
The final Modifier
❑The final class cannot be extended:
final class Math {
...
}
30
Abstract Classes and Abstract Methods
GeometricObject
GeometricObject
Circle
Circle
Rectangle
Rectangle
TestGeometricObject
TestGeometricObject
31 31
abstract method in abstract class
An abstract method cannot be contained in a
nonabstract class. If a subclass of an abstract
superclass does not implement all the abstract
methods, the subclass must be defined abstract. In
other words, in a nonabstract subclass extended from
an abstract class, all the abstract methods must be
implemented, even if they are not used in the
subclass.
32 32
object cannot be created from abstract
class
An abstract class cannot be instantiated using
the new operator, but you can still define its
constructors, which are invoked in the
constructors of its subclasses. For instance,
the constructors of GeometricObject are
invoked in the Circle class and the Rectangle
class.
33 33
abstract class without abstract method
34 34
superclass of abstract class may be
concrete
35 35
abstract class as type
37 37
Abstract Classes and Abstract Methods
GeometricObject
GeometricObject
Circle
Circle
Rectangle
Rectangle
TestGeometricObject
TestGeometricObject
38 38
public abstract class GeometricObject {
private String color = "white"; public boolean isFilled() {
private boolean filled; return filled;
private java.util.Date dateCreated; }
43 43
Realization
• Realization is a relationship between the blueprint class and
the object containing its respective implementation level
details. This object is said to realize the blueprint class. In
other words, you can understand this as the relationship
between the interface and the implementing class.
What is an interface?
Why is an interface useful?
An interface is a classlike construct that contains only
constants and abstract methods. In many ways, an
interface is similar to an abstract class, but the intent of
an interface is to specify common behavior for objects.
For example, you can specify that the objects are
comparable, edible, cloneable using appropriate
interfaces.
45 45
Define an Interface
To distinguish an interface from a class, Java uses the
following syntax to define an interface:
public interface InterfaceName {
constant declarations;
abstract method signatures;
}
Example:
public interface Edible {
/** Describe how to eat */
public abstract String howToEat();
}
46 46
Interface is a Special Class
An interface is treated like a special class in Java.
Each interface is compiled into a separate bytecode file,
just like a regular class. Like an abstract class, you cannot
create an instance from an interface using the new
operator, but in most cases you can use an interface more
or less the same way you use an abstract class.
For example, you can use an interface as a data type for a
variable, as the result of casting, and so on.
47 47
Omitting Modifiers in Interfaces
All data fields are public final static and all methods are public
abstract in an interface. For this reason, these modifiers can be
omitted, as shown below:
48 48
Interfaces vs. Abstract Classes
In an interface, the data must be constants; an abstract class can
have all types of data.
Each method in an interface has only a signature without
implementation; an abstract class can have concrete methods.
49 49
Interfaces vs. Abstract Classes, cont.
All classes share a single root, the Object class, but there is no single root for
interfaces. Like a class, an interface also defines a type. A variable of an interface
type can reference any instance of the class that implements the interface. If a class
extends an interface, this interface plays the same role as a superclass. You can use
an interface as a data type and cast a variable of an interface type to its subclass,
and vice versa.
60 60
Generic sort Method
Let n be an Integer object, s be a String object, and d be a
Date object. All the following expressions are true.
SortComparableObjects
61 61
import java.math.*;
ComparableRectangle SortRectangles
ComparableRectangle SortRectangles
63 63
public class ComparableRectangle extends Rectangle
implements Comparable<ComparableRectangle> {
/** Construct a ComparableRectangle with specified properties */
public ComparableRectangle(double width, double height) {
super(width, height);
}
@Override // Override the compareTo method defined in Comparable
public int compareTo(ComparableRectangle o) {
if (getArea() > o.getArea())
return 1;
else if (getArea() < o.getArea())
return -1;
else
return 0;
}
@Override // Implement the toString method in GeometricObject
public String toString() {
return "Width: " + getWidth() + " Height: " + getHeight() +
" Area: " + getArea();
}
}
public class SortRectangles {
public static void main(String[] args) {
ComparableRectangle[] rectangles = {
new ComparableRectangle(3.4, 5.4),
new ComparableRectangle(13.24, 55.4),
new ComparableRectangle(7.4, 35.4),
new ComparableRectangle(1.4, 25.4)};
java.util.Arrays.sort(rectangles);
for (Rectangle rectangle: rectangles) {
System.out.print(rectangle + " ");
System.out.println();
}
}
}
Width: 3.4 Height: 5.4 Area: 18.36
Width: 1.4 Height: 25.4 Area: 35.559999999999995
Width: 7.4 Height: 35.4 Area: 261.96
Width: 13.24 Height: 55.4 Area: 733.496
compareTo
• The Object class contains the equals method, which is intended for the subclasses of the
Object class to override in order to compare whether the contents of the objects are the
same.
• Suppose the Object class contains the compareTo method, as defined in the Comparable
interface; the sort method can be used to compare a list of any objects. Whether a
compareTo method should be included in the Object class is debatable.
• Since the compareTo method is not defined in the Object class, the Comparable interface
is defined in Java to enable objects to be compared if they are instances of the
Comparable interface.
• compareTo should be consistent with equals.
• That is, for two objects o1 and o2, o1.compareTo(o2) == 0 if and only if o1.equals(o2) is
true.
• Therefore, you should also override the equals method in the ComparableRectangle class
to return true if two rectangles have the same area.
The Cloneable Interfaces
• Cloning is a technique for creating an exact copy of Java objects. By copy,
we mean that all the data are replicated in the newly copied object.
• To create an exact copy of an object in Java, we use a Clonable interface. A
Java class implements the Clonable interface to create a clone of the class
object. The Cloneable interface exists in the java.lang package.
• A Cloneable interface in Java is used to clone an object in the Java class.
The object class has a clone() method, which creates an exact copy of the
object. The cloned object has a separate space in memory where the copy
of the original object is stored. If a class doesn't implement the clonable
interface and we try to clone the object, we get an exception called
CloneNotSupportedException.
The Cloneable Interfaces
Marker Interface: An empty interface.
A marker interface does not contain constants or methods.
It is used to denote that a class possesses certain desirable
properties. A class that implements the Cloneable
interface is marked cloneable, and its objects can be
cloned using the clone() method defined in the Object
class.
package java.lang;
public interface Cloneable {
}
68 68
Examples
Many classes (e.g., Date and Calendar) in the Java library implement
Cloneable. Thus, the instances of these classes can be cloned. For
example, the following code
displays
calendar == calendarCopy is false
calendar.equals(calendarCopy) is true
69 69
Implementing Cloneable Interface
To define a custom class that implements the Cloneable
interface, the class must override the clone() method in
the Object class. The following code defines a class
named House that implements Cloneable and
Comparable.
House
House
70 70
@Override /** Override the protected
public class House implements Cloneable,
clone method defined in
Comparable<House> {
the Object class, and strengthen its
private int id;
accessibility */
private double area;
public Object clone() {
private java.util.Date whenBuilt;
try {
return super.clone();
public House(int id, double area) {
}
this.id = id;
catch (CloneNotSupportedException ex) {
this.area = area;
return null;
whenBuilt = new java.util.Date();
}
}
}
public int getId() {
@Override // Implement the compareTo
return id;
method defined in Comparable
}
public int compareTo(House o) {
public double getArea() {
if (area > o.area)
return area;
return 1;
}
else if (area < o.area)
public java.util.Date getWhenBuilt() {
return -1;
return whenBuilt;
else
}
return 0;
}
}
Shallow vs. Deep Copy
• You can now create an object of the House class and create an identical copy from it, as follows:
• House house1 = new House(1, 1750.50);
• House house2 = (House)house1.clone();
• house1 and house2 are two different objects with identical contents. The clone method in the
Object class copies each field from the original object to the target object.
• If the field is of a primitive type, its value is copied. For example, the value of area (double type) is
copied from house1 to house2.
• If the field is of an object, the reference of the field is copied. For example, the field whenBuilt is
of the Date class, so its reference is copied into house2
• Therefore, house1.whenBuilt == house2.whenBuilt is true,
• although house1 == house2 is false.
• This is referred to as a shallow copy rather than a deep copy, meaning if the field is of an object
type, the object’s reference is copied rather than its contents.
Shallow vs. Deep Copy
House house1 = new House(1, 1750.50);
House house2 = (House)house1.clone();
Shallow
Copy
73 73
Shallow vs. Deep Copy
To perform a deep copy for a House object, replace the clone() method in lines 26–33 with the following
code
Deep
Copy
75 75
Thanks
References
• Introduction to Java Programming and Data Structures, Comprehensive Version 12th
Edition, by Y. Liang (Author), Y. Daniel Liang
• This slides based on slides provided by Introduction to Java Programming and Data Structures,
Comprehensive Version 12th Edition, by Y. Liang (Author), Y. Daniel Liang
Advanced Programming Language
Dr. Ahmed Hesham Mostafa
Dr. Mohamed Atia
Lecture 6 – Exceptions handling
Exception
• In Java, runtime errors are thrown as exceptions.
• An exception is an object that represents an error or a condition that
prevents execution from proceeding normally.
• If the exception is not handled, the program will terminate
abnormally.
• How can you handle the exception so the program can continue to
run or else terminate gracefully?
Exception-Handling Overview
• Show runtime error
Quotient
Quotient
QuotientWithIf
• With a method
QuotientWithIf
QuotientWithIf
Exception-Handling Overview
Show runtime error
Enter two integers: 1 0
Exception in thread "main"
import java.util.Scanner; java.lang.ArithmeticException: / by zero
public class Main { at Main.main(Main.java:9)
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Prompt the user to enter two integers
System.out.print("Enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
System.out.println(number1 + " / " + number2 + " is " +(number1 / number2));
}
}
Exception-Handling Overview
Fix it using an if statement
import java.util.Scanner;
public class Main { Enter two integers: 1 0
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Divisor cannot be zero
System.out.print("Enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
if (number2 != 0)
System.out.println(number1 + " / " + number2 + " is " +
(number1 / number2));
else
System.out.println("Divisor cannot be zero ");
}
}
Exception-Handling
public class Main { Overview
public static int quotient(int number1, int number2) {
if (number2 == 0) { With a method
System.out.println("Divisor cannot be zero");
System.exit(1);
} Enter two integers: 1 0
return number1 / number2; Divisor cannot be zero
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
int result = quotient(number1, number2);
System.out.println(number1 + " / " + number2 + " is "+ result);
}}
Exception-Handling Overview
With a method
• The method quotient (previous slide) returns the quotient of two
integers. If number2 is 0, it cannot return a value, so the program is
terminated in line 7.
• This is clearly a problem. You should not let the method terminate
the program—the caller should decide whether to terminate the
program.
• How can a method notify its caller an exception has occurred? Java
enables a method to throw an exception that can be caught and
handled by the caller . as shown in next slide.
import java.util.Scanner;
public class Main {
public static int quotient(int number1, int number2) {
if (number2 == 0)
using exception
throw new ArithmeticException("Divisor cannot be zero"); handling
return number1 / number2;
}
public static void main(String[] args) {
Enter two integers: 1 0
Scanner input = new Scanner(System.in);
System.out.print("Enter two integers: "); Exception: an integer cannot be divided by zero
int number1 = input.nextInt(); Execution continues ...
int number2 = input.nextInt();
try {
int result = quotient(number1, number2);
System.out.println(number1 + " / " + number2 + " is " + result);
}
catch (ArithmeticException ex) {
System.out.println("Exception: an integer " +"cannot be divided by zero
");
}
System.out.println("Execution continues ...");
}
}
using exception handling
• The value thrown, in this case new ArithmeticException("Divisor
cannot be zero"), is called an exception.
• The execution of a throw statement is called throwing an exception.
• The exception is an object created from an exception class. In this
case, the exception class is java.lang.ArithmeticException.
• The constructor ArithmeticException(str) is invoked to construct an
exception object, where str is a message that describes the exception.
using exception handling
• When an exception is thrown, the normal execution flow is
interrupted. As the name suggests, to “throw an exception” is to pass
the exception from one place to another.
• The statement for invoking the method is contained in a try block.
The try block contains the code that is executed in normal scinario.
• The exception is caught by the catch block.
• The code in the catch block is executed to handle the exception.
Afterward, the statement after the catch block is executed.
using exception handling
• The throw statement is similar to a method call, but instead of calling
a method, it calls a catch block.
• In this sense, a catch block is like a method definition with a
parameter that matches the type of the value being thrown.
• Unlike a method, however, after the catch block is executed, the
program control does not return to the throw statement; instead, it
executes the next statement after the catch block.
using exception handling
• The identifier ex in the catch–block header catch
(ArithmeticException ex)
• acts very much like a parameter in a method. Thus, this parameter is
referred to as a catch block parameter.
• The type (e.g., ArithmeticException) preceding ex specifies what kind
of exception the catch block can catch.
• Once the exception is caught, you can access the thrown value from
this parameter in the body of a catch block.
using exception handling
• In summary, a template for a try-throw-catch block may look as follows:
try {
Code to run;
A statement or a method that may throw an exception;
More code to run;
}
catch (type ex) {
Code to process the exception;
}
using exception handling
• An exception may be thrown directly by using a throw statement in a
try block, or by invoking a method that may throw an exception.
• The main method invokes quotient (line 20). If the quotient method
executes normally, it returns a value to the caller.
• If the quotient method encounters an exception, it throws the
exception back to its caller.
• The caller’s catch block handles the exception.
Exception Advantages
• Now you see 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.
• Often the called method does not know what to do in case of error.
Exception V.S If-else
• You should use if / else to handle all cases you expect. You
should not use try {} catch {} to handle everything (in most cases)
because a useful Exception could be raised and you can learn about
the presence of a bug from it.
• You should use try {} catch {} in situations where you suspect
something can/will go wrong and you don't want it to bring down the
whole system, like network timeout/file system access problems, files
doesn't exist, etc.
Handling InputMismatchException
InputMismatchExceptionDemo
InputMismatchExceptionDemo
17
import java.util.*; When executing input.nextInt() (line 11), an
public class InputMismatchExceptionDemo { InputMismatchException occurs if the input entered is not an
public static void main(String[] args) { integer. Suppose 3.5 is entered. An InputMismatchException
Scanner input = new Scanner(System.in); occurs and the control is transferred to the catch block. The
boolean continueInput = true; statements in the catch block are now executed. The
do { statement input.nextLine() in line 22 discards the current
try { input line so the user can enter a new line of input. The
System.out.print("Enter an integer: "); variable continueInput controls the loop. Its initial value is
int number = input.nextInt(); true (line 6) and it is changed to false (line 17) when a valid
// Display the result input is received. Once a valid input is received, there is no
System.out.println("The number entered is " + number); need to continue the input.
continueInput = false;
}
catch (InputMismatchException ex) {
System.out.println("Try again. (" +
"Incorrect input: an integer is required)");
input.nextLine(); // discard input
}
} while (continueInput);
}
}
Exception Types
ClassNotFoundException
ArithmeticException
IOException
Exception NullPointerException
RuntimeException
IndexOutOfBoundsException
Many more classes
Object Throwable IllegalArgumentException
Error VirtualMachineError
ArithmeticException
IOException
Exception NullPointerException
RuntimeException
IndexOutOfBoundsException
Many more classes
Object Throwable IllegalArgumentException
20
Exceptions
Exception describes errors ClassNotFoundException
caused by your program.
These errors can be caught ArithmeticException
IOException
and handled by your
program. Exception NullPointerException
RuntimeException
IndexOutOfBoundsException
Many more classes
Object Throwable IllegalArgumentException
Error VirtualMachineError
21
Runtime Exceptions
ClassNotFoundException
ArithmeticException
IOException
Exception NullPointerException
RuntimeException
IndexOutOfBoundsException
Many more classes
Object Throwable IllegalArgumentException
22
Examples of Subclasses of Exception
• ClassNotFoundException Attempt to use a class that does not exist.
This exception would occur, for example, if you tried to run a
nonexistent class using the java command or if your program were
composed of, say, three class files, only two of which could be found.
• IOException Related to input/output operations, such as invalid input,
reading past the end of a file, and opening a nonexistent file.
Examples of subclasses of IOException are InterruptedIOException,
EOFException (EOF is short for End of File), and
FileNotFoundException.
Checked Exceptions vs. Unchecked Exceptions
• 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.
Unchecked Exceptions
• In most cases, unchecked exceptions reflect programming logic errors
that are not recoverable.
• For example, a NullPointerException is thrown if you access an object
through a reference variable before an object is assigned to it; an
IndexOutOfBoundsException is thrown if you access an element in an
array outside the bounds of the array.
• These are the logic errors that should be corrected in the program.
Unchecked exceptions can occur anywhere in the program.
• To avoid overuse of try-catch blocks, Java does not mandate you to
write code to catch unchecked exceptions.
Unchecked Exceptions
ClassNotFoundException
ArithmeticException
IOException
Exception NullPointerException
RuntimeException
IndexOutOfBoundsException
Many more classes
Object Throwable IllegalArgumentException
26
Declaring, Throwing, and Catching Exceptions
IllegalArgumentException ex =
new IllegalArgumentException("Wrong Argument");
throw ex;
Or, if you prefer, you can use the following:
throw new IllegalArgumentException("Wrong Argument");
Throwing Exceptions 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");
}
Note
• IllegalArgumentException is an exception class in the Java API.
• In general, each exception class in the Java API has at least two
constructors: a no-arg constructor and a constructor with a String
argument that describes the exception.
• This argument is called the exception message, which can be
obtained by invoking getMessage() from an exception object.
TIP
• The keyword to declare an exception is throws, and the keyword to
throw an exception is throw .
Catching Exceptions
try {
statements; // Statements that may throw
exceptions
}
catch (Exception1 exVar1) {
handler for exception1;
}
catch (Exception2 exVar2) {
handler for exception2;
}
...
catch (ExceptionN exVar3) {
handler for exceptionN;
}
Catching Exceptions
• If one of the statements inside the try block throws an exception,
Java skips the remaining statements in the try block and starts
the process of finding the code to handle the exception.
• The code that handles the exception is called the exception
handler; it is found by propagating the exception backward
through a chain of method calls, starting from the current
method.
• Each catch block is examined in turn, from first to last, to see
whether the type of the exception object is an instance of the
exception class in the catch block.
Catching Exceptions
• If so, the exception object is assigned to the variable declared
and the code in the catch block is executed.
• If no handler is found, Java exits this method, passes the
exception to the method’s caller, and continues the same process
to find a handler.
• If no handler is found in the chain of methods being invoked, the
program terminates and prints an error message on the console.
• The process of finding a handler is called catching a exception.
Catching Exceptions
main method { method1 { method2 { An exception
... ... ... is thrown in
try { try { try { method3
... ... ...
invoke method1; invoke method2; invoke method3;
statement1; statement3; statement5;
} } }
catch (Exception1 ex1) { catch (Exception2 ex2) { catch (Exception3 ex3) {
Process ex1; Process ex2; Process ex3;
} } }
statement2; statement4; statement6;
} } }
Call Stack
method3
method2 method2
...
}
Getting Information from Exceptions
• An exception object contains valuable information about the exception.
You may use the following instance methods in the java.lang.Throwable
class to get information regarding the exception, as shown in Figure 12.4.
The printStackTrace() method prints stack trace
public class Main {
public static void main(String[] args) {
try {
System.out.println(sum(new int[] {1, 2, 3, 4, 5}));
}
catch (Exception ex) {
ex.printStackTrace();
System.out.println("\n" + ex.getMessage());
System.out.println("\n" + ex.toString());
System.out.println("\nTrace Info Obtained from getStackTrace");
StackTraceElement[] traceElements = ex.getStackTrace();
for (int i = 0; i < traceElements.length; i++) {
System.out.print("method " + traceElements[i].getMethodName());
System.out.print("(" + traceElements[i].getClassName() + ":");
System.out.println(traceElements[i].getLineNumber() + ")");
}
}
}
private static int sum(int[] list) {
int result = 0;
for (int i = 0; i <= list.length; i++)
result += list[i];
return result;
}}
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at Main.sum(Main.java:23) printStackTrace()printStackTrace()
at Main.main(Main.java:4)
CircleWithException
TestCircleWithException
TestCircleWithException
public class CircleWithException {
/** The radius of the circle */
private double radius; public void setRadius(double newRadius)
/** The number of the objects created */ throws IllegalArgumentException {
private static int numberOfObjects = 0; if (newRadius >= 0)
/** Construct a circle with radius 1 */ radius = newRadius;
public CircleWithException() { else
this(1.0); throw new IllegalArgumentException(
} "Radius cannot be negative");
/** Construct a circle with a specified radius */ }
public CircleWithException(double newRadius) { /** Return numberOfObjects */
setRadius(newRadius); public static int getNumberOfObjects() {
numberOfObjects++; return numberOfObjects;
} }
/** Return radius */ /** Return the area of this circle */
public double getRadius() { public double findArea() {
return radius; return radius * radius * 3.14159;
} }
}
public class Main {
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
54
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
55
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
56
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
57
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
58
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
59
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
60
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
61
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
62
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
63
animation
Next statement;
Liang, Introduction to Java Programming and Data Structures, Twelfth Edition, (c) 2020 Pearson Education, Inc. All rights
reserved.
64
When Using Exceptions
• 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 to Throw Exceptions
• 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 to Use Exceptions
• 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. For example, the following code
try {
System.out.println(refVar.toString());
}
catch (NullPointerException ex) {
System.out.println("refVar is null");
}
When to Use Exceptions
• is better to be replaced by
if (refVar != null)
System.out.println(refVar.toString());
else
System.out.println("refVar is null");
Defining Custom Exception Classes
• 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.
Custom Exception Class Example
• In Listing 13.8, the setRadius method throws an exception if the
radius is negative. Suppose you wish to pass the radius to the handler,
you have to create a custom exception class.
InvalidRadiusException
InvalidRadiusException
CircleWithRadiusException
CircleWithRadiusException
TestCircleWithRadiusException
TestCircleWithRadiusException
public class InvalidRadiusException extends Exception {
private double radius;
public InvalidRadiusException(double radius) {
super("Invalid radius " + radius);
this.radius = radius;
}
public double getRadius() {
return radius;
}
}
public class CircleWithRadiusException {
private double radius;
private static int numberOfObjects = 0; public void setRadius(double newRadius)
throws InvalidRadiusException {
public CircleWithRadiusException() {
if (newRadius >= 0)
this(1.0); radius = newRadius;
} else
public CircleWithRadiusException(double newRadius) { throw new InvalidRadiusException(newRadius);
try { }
setRadius(newRadius);
numberOfObjects++; /** Return numberOfObjects */
} public static int getNumberOfObjects() {
catch (InvalidRadiusException ex) { return numberOfObjects;
}
ex.printStackTrace();
} /** Return the area of this circle */
} public double findArea() {
public double getRadius() { return radius * radius * 3.14159;
return radius; }
} }
public class Main {
public static void main(String[] args) {
try {
CircleWithRadiusException c1 = new CircleWithRadiusException(5);
c1.setRadius(-5);
CircleWithRadiusException c3 = new CircleWithRadiusException(0);
}
catch (InvalidRadiusException ex) {
System.out.println(ex);
}
import java.io.*;
class GFG {
public static void main(String[] args)
{
// Try block to check for exceptions
try (FileOutputStream fos = new FileOutputStream("gfgtextfile.txt")) {
String text = "Hello World. This is my java program";
byte arr[] = text.getBytes();
fos.write(arr);
}
catch (Exception e) {
System.out.println(e);
}
System.out.println(
"Resource are closed and message has been written into the
gfgtextfile.txt");
}
}
import java.io.*;
class GFG {
public static void main(String[] args)
{
try (FileOutputStream fos = new FileOutputStream("outputfile.txt");
BufferedReader br =
new BufferedReader( new FileReader("gfgtextfile.txt"))
)
{
while ((text = br.readLine()) != null) {
byte arr[] = text.getBytes();
}
• php - What is the advantage of using try {} catch {} versus if {} else {} - Stack Overflow
Advanced Programming Language
Dr. Ahmed Hesham Mostafa
Dr. Mohamed Atia
Lecture 7 – IO Files
Files and Streams
• File streams can be used to input and output data as bytes or characters.
• Streams that input and output bytes are known as byte-based streams,
representing data in its binary format.
• Streams that input and output characters are known as character-based
streams, representing data as a sequence of characters.
• Files that are created using byte-based streams are referred to as binary files.
• Files created using character-based streams are referred to as text files. Text
files can be read by text editors.
• Binary files are read by programs that understand the specific content of the
file and the ordering of that content.
Files and Streams (cont.)
• Can perform input and output of objects or variables of primitive data types
without having to worry about the details of converting such values to byte
format.
• To perform such input and output, objects of classes ObjectInputStream and
ObjectOutputStream can be used together with the byte-based file stream
classes FileInputStream and FileOutputStream.
• The complete hierarchy of classes in package java.io can be viewed in the
online documentation at
• http://download.oracle.com/javase/6/docs/api/java/io/packag
e-tree.html
Files and Streams (cont.)
TestFileClass
import java.io.File;
public class Main {
public static void main(String[] args) {
File file = new File("C:\\Users\\ahmed\\Desktop\\a.txt");
System.out.println("Does it exist? " + file.exists()); Does it exist? true
System.out.println("The file has " + file.length() + " bytes"); The file has 373 bytes
System.out.println("Can it be read? " + file.canRead()); Can it be read? true
System.out.println("Can it be written? " + file.canWrite()); Can it be written? true
System.out.println("Is it a directory? " + file.isDirectory()); Is it a directory? false
System.out.println("Is it a file? " + file.isFile()); Is it a file? true
System.out.println("Is it absolute? " + file.isAbsolute()); Is it absolute? true
System.out.println("Is it hidden? " + file.isHidden()); Is it hidden? false
System.out.println("Absolute path is " + Absolute path is C:\Users\ahmed\Desktop\a.txt
file.getAbsolutePath()); Last modified on Thu Dec 08 23:56:05 EET 2022
System.out.println("Last modified on " +
new java.util.Date(file.lastModified()));
}
}
Text I/O
• A File object encapsulates the properties of a file or a path, but does
not contain the methods for reading/writing data from/to a file.
• In order to perform I/O, you need to create objects using appropriate
Java I/O classes.
• The objects contain the methods for reading/writing data from/to a
file.
• This section introduces how to read/write strings and numeric values
from/to a text file using the Scanner and PrintWriter classes.
Writing Data Using PrintWriter
java.io.PrintWriter
+PrintWriter(filename: String) Creates a PrintWriter for the specified file.
+print(s: String): void Writes a string.
+print(c: char): void Writes a character.
+print(cArray: char[]): void Writes an array of character.
+print(i: int): void Writes an int value.
WriteData
case 5:
admin.displayStudents();
break;
case 6:
System.exit(0);
}
}
public class Admin { public void addNewStudent(int id, String fname, String lname, int age, int level, double GPA) {
String user; pass, fname, lname; Student x = new Student( id, fname, lname, age, level, GPA);
int id, age; if (x.addStudent()) {
public Admin() { } System.out.println(x.toString() + "Added Successfully ... !");
public Admin(int id, String fname, String lname, int age) { } else {
this.id = id;
this.fname = fname; }
System.out.println("Failed to insert ... !");
Admin Class
this.lname = lname; }
this.age = age; public void displayStudents() {
} Student x = new Student();
public int getId() { System.out.println(x.displayAllStudents());
return id; }
} public void searchForStudent(int id) {
public void setId(int id) { Student x = new Student();
this.id = id; System.out.println(x.searchStudent(id));
} }
public String getFname() { public void updateStudent(int oldID, Student newStudentValues) {
return fname; Student x = new Student();
} x.updateStudent(oldID, newStudentValues);
public void setFname(String fname) { System.out.println("Updated Successfully ... !");
this.fname = fname; }
} public void deleteStudent(int Id) {
public String getLname() { Student x = new Student();
return lname; x.deleteStudent(Id);
} System.out.println("deleted Successfully ... !");
public void setLname(String lname) { }
this.lname = lname; }
}
public int getAge() {
return age; }
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList; FileManger Class
import java.util.Scanner;
public class FileManger {
public boolean write(String Query, String FilePath, boolean appendType) {
PrintWriter writter = null;
try {
System.out.print("\nwritting in ! " + FilePath);
writter = new PrintWriter(new FileWriter(new File(FilePath), appendType));
writter.println(Query);
System.out.println(" ... Done ! ");
return true;
} catch (IOException e) {
System.out.println(e);
Go To binary Version
Go To binary Version
} finally {
writter.close();
}
return false;
}
public ArrayList<Object> read(String FilePath) {
Scanner Reader = null;
try {
System.out.println("Reading ! From " + FilePath);
Reader = new Scanner(new File(FilePath));
} catch (FileNotFoundException e) {
System.out.println(e+" Cann't find file");
FileManger Class
}
ArrayList<Student> Students = new ArrayList<Student>();
Student x;
while (Reader.hasNext()) {
x = new Student();
String Line = Reader.nextLine();
String[] seprated = Line.split(",");
x.setId(Integer.parseInt(seprated[0]));
x.setFname(seprated[1]);
x.setLname(seprated[2]);
x.setAge(Integer.parseInt(seprated[3]));
x.setLevel(Integer.parseInt(seprated[4]));
x.setGPA(Double.parseDouble(seprated[5]));
Students.add(x);
}
return (ArrayList<Object>) (Object) Students;
}
}
import java.util.ArrayList;
public class Student {
private int level;
private int age; public void setLname(String lname) {
private double GPA; this.lname = lname;
private String fname; }
private String lname; public void setLevel(int level) {
private int id; this.level = level;
private final String studentFileName = "Students.txt"; }
public static ArrayList<Student> Students = new ArrayList<Student>();
private FileManger fileManger=new FileManger(); public int getAge() {
Student Class
public Student(){} return age;
public Student(int id, String fname, String lname, int age, int level, double GPA) { }
this.id=id;
this.fname=fname; public void setAge(int age) {
this.lname=lname; this.age = age;
this.age=age; }
this.level = level;
this.GPA = GPA; public void setGPA(double GPA) {
} this.GPA = GPA;
public int getId() { }
return id;
} public int getLevel() {
public void setId(int id) { return this.level;
this.id = id; }
}
public String getFname() { public double getGPA() {
return fname; return this.GPA;
} }
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public boolean addStudent() {
if (fileManger.write(getStudentData(), studentFileName, true)) {
return true;
} else {
return false; Student Class
}
}
Go To binary Version
}
private int getStudentIndex(int id){
for (int i = 0; i < Students.size(); i++)
if(Students.get(i).getId() == id)
return i;
Student Class
return -1;
}
Program
Input stream
Input object
created from an 01011…1001 File
input class
output.close();
Text File vs. Binary File
• Data stored in a text file are represented in human-readable form.
• Data stored in a binary file are represented in binary form. You cannot read
binary files. Binary files are designed to be read by programs.
• For example, the Java source programs are stored in text files and can be
read by a text editor, but the Java classes are stored in binary files and are
read by the JVM. The advantage of binary files is that they are more
efficient to process than text files.
• Although it is not technically precise and correct, you can imagine that a
text file consists of a sequence of characters and a binary file consists of a
sequence of bits. For example, the decimal integer 199 is stored as the
sequence of three characters: '1', '9', '9' in a text file and the same integer
is stored as a byte-type value C7 in a binary file, because decimal 199
equals to hex C7.
Binary I/O
• Text I/O requires encoding and decoding.
• The JVM converts a Unicode to a file specific encoding when writing a
character and coverts a file specific encoding to a Unicode when
reading a character.
• Binary I/O does not require conversions. When you write a byte to a
file, the original byte is copied into the file. When you read a byte
from a file, the exact byte in the file is returned.
Binary I/O Classes
InputStream
The value returned is a byte as an int type.
java.io.InputStream
+read(): int Reads the next byte of data from the input stream. The value byte is returned as
an int value in the range 0 to 255. If no byte is available because the end of
the stream has been reached, the value –1 is returned.
+read(b: byte[]): int Reads up to b.length bytes into array b from the input stream and returns the
actual number of bytes read. Returns -1 at the end of the stream.
+read(b: byte[], off: int, Reads bytes from the input stream and stores into b[off], b[off+1], …,
len: int): int b[off+len-1]. The actual number of bytes read is returned. Returns -1 at the
end of the stream.
+available(): int Returns the number of bytes that can be read from the input stream.
+close(): void Closes this input stream and releases any system resources associated with the
stream.
+skip(n: long): long Skips over and discards n bytes of data from this input stream. The actual
number of bytes skipped is returned.
+markSupported(): boolean Tests if this input stream supports the mark and reset methods.
+mark(readlimit: int): void Marks the current position in this input stream.
+reset(): void Repositions this stream to the position at the time the mark method was last
called on this input stream.
35
OutputStream
java.io.OutputStream
+write(int b): void Writes the specified byte to this output stream. The parameter b is an int value.
(byte)b is written to the output stream.
+write(b: byte[]): void Writes all the bytes in array b to the output stream.
+write(b: byte[], off: int, Writes b[off], b[off+1], …, b[off+len-1] into the output stream.
len: int): void
+close(): void Closes this output stream and releases any system resources associated with the
stream.
+flush(): void Flushes this output stream and forces any buffered output bytes to be written out.
36
FileInputStream/FileOutputStream
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
If the file does not exist, a new file would be created. If the file already exists, the
first two constructors would delete the current contents in the file. To retain the
current content and append new data into the file, use the last two constructors by
passing true to the append parameter.
import java.io.*;
public class TestFileStream {
public static void main(String[] args) throws IOException {
try (
// Create an output stream to the file
FileOutputStream output = new
FileOutputStream("temp.dat");
){
// Output values to the file
for (int i = 1; i <= 10; i++)
output.write(i);
}
try (
// Create an input stream for the file
FileInputStream input = new FileInputStream("temp.dat");
){
// Read values from the file
int value;
while ((value = input.read()) != -1)
System.out.print(value + " ");
}
}
}
FilterInputStream/FilterOutputStream
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
Filter streams are streams that filter bytes for some purpose. The basic byte input
stream provides a read method that can only be used for reading bytes. If you want
to read integers, doubles, or strings, you need a filter class to wrap the byte input
stream. Using a filter class enables you to read integers, doubles, and strings instead
of bytes and characters. FilterInputStream and FilterOutputStream are the base
classes for filtering data. When you need to process primitive numeric types, use
DatInputStream and DataOutputStream to filter bytes.
41
DataInputStream/DataOutputStream
DataInputStream reads bytes from the stream
and converts them into appropriate primitive
type values or strings.
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
43
DataOutputStream
DataOutputStream extends FilterOutputStream and implements the
DataOutput interface.
44
What is UTF
• UTF in Java refers to Unicode Transformation Format, which is a
standard for encoding characters into a sequence of bytes. Java uses
UTF encoding for character representation, particularly UTF-8 and
Modified UTF-8, in its various classes and APIs.
• UTF-8:
• A variable-length encoding that represents every Unicode character.
• It uses 1 to 4 bytes per character.
• Java supports UTF-8 for reading and writing text files and network
communication.
• Widely used because of its backward compatibility with ASCII (characters in
the range 0-127 use one byte).
What is UTF
• Modified UTF-8:
• A variation of UTF-8 used internally in Java for serialization (e.g., in DataInput
and DataOutput streams).
• Differs from standard UTF-8 in two ways:It uses two bytes for null (\u0000)
instead of one.
• It encodes surrogate pairs directly as three bytes, unlike UTF-8, which
encodes them as six bytes.
• Used for efficiency in JVM-internal operations like .class file representation.
• Example: In a serialized form or when using Java DataInputStream and
DataOutputStream
Where is UTF Used in Java?
• String Encoding and Decoding:
• String.getBytes() and new String(byte[], Charset) support UTF encoding.
• File I/O:
• Classes like InputStreamReader, OutputStreamWriter, and Files use UTF-8 by
default in many cases.
• Serialization:
• Modified UTF-8 is used in DataInputStream and DataOutputStream
Why UTF-8? What is UTF-8?
• UTF-8 is a coding scheme that allows systems to operate with both ASCII
and Unicode efficiently. Most operating systems use ASCII. Java uses
Unicode.
1.Networking: Protocols and web services often rely on UTF-8 for text-based
communication
• The ASCII character set is a subset of the Unicode character set. Since most
applications need only the ASCII character set, it is a waste to represent an
8-bit ASCII character as a 16-bit Unicode character. The UTF-8 is an
alternative scheme that stores a character using 1, 2, or 3 bytes.
• ASCII values (less than 0x7F) are coded in one byte. Unicode values less
than 0x7FF are coded in two bytes. Other Unicode values are coded in
three bytes.
Characters and Strings in Binary I/O
• A Unicode consists of two bytes. The writeChar(char c) method writes the
Unicode of character c to the output. The writeChars(String s) method
writes the Unicode for each character in the string s to the output.
• The writeBytes(String s) method writes the lower byte of the Unicode for
each character in the string s to the output. The high byte of the Unicode is
discarded. The writeBytes method is suitable for strings that consist of
ASCII characters, since an ASCII code is stored only in the lower byte of a
Unicode. If a string consists of non-ASCII characters, you have to use the
writeChars method to write the string.
• The writeUTF(String s) method writes a string using the UTF coding
scheme. UTF is efficient for compressing a string with Unicode characters.
Using DataInputStream/DataOutputStream
Data streams are used as wrappers on existing input and output streams to filter
data in the original stream. They are created using the following constructors:
public DataInputStream(InputStream instream)
public DataOutputStream(OutputStream outstream)
The statements given below create data streams. The first statement creates an
input stream for file in.dat; the second statement creates an output stream for file
out.dat.
DataInputStream infile =
new DataInputStream(new FileInputStream("in.dat")); TestDataStream
Run
52
Order and Format
• CAUTION: You have to read the data in the same order and same
format in which they are stored. For example, since names are
written in UTF-8 using writeUTF, you must read names using readUTF.
• Checking End of File
• TIP: If you keep reading data at the end of a stream, an EOFException
would occur. So how do you check the end of a file? You can use
input.available() to check it. input.available() == 0 indicates that it is
the end of a file.
BufferedInputStream/BufferedOutputStream
• can be used to speed up input and output by reducing the number of
disk reads and writes.
• Using BufferedInputStream, the whole block of data on the disk is
read into the buffer in the memory once.
• The individual data are then loaded to your program from the buffer.
• Using BufferedOutputStream, the individual data are first written to
the buffer in the memory. When the buffer is full, all data in the
buffer are written to the disk once
Constructing
BufferedInputStream/BufferedOutputStream
// Create a BufferedInputStream
public BufferedInputStream(InputStream in)
public BufferedInputStream(InputStream in, int bufferSize)
// Create a BufferedOutputStream
public BufferedOutputStream(OutputStream out)
public BufferedOutputStream(OutputStreamr out, int bufferSize)
55
BufferedInputStream/
BufferedOutputStream Using buffers to speed up I/O
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
The program copies a source file to a target file and displays the number
of bytes in the file. If the source does not exist, tell the user the file is not
found. If the target file already exists, tell the user the file already exists.
Copy
Run
Copy Run
57
import java.io.*;
public class Copy {
/** Main method
@param args[0] for sourcefile
@param args[1] for target file */
public static void main(String[] args) throws IOException {
// Check command-line parameter usage
if (args.length != 2) {
System.out.println(
"Usage: java Copy sourceFile targetfile");
System.exit(1);
}
// Check if source file exists
File sourceFile = new File(args[0]);
if (!sourceFile.exists()) {
System.out.println("Source file " + args[0] + " does not exist");
System.exit(2);
}
// Check if target file exists
File targetFile = new File(args[1]);
if (targetFile.exists()) {
System.out.println("Target file " + args[1] + " already exists");
System.exit(3);
}
try (
// Create an input stream
BufferedInputStream input =
new BufferedInputStream(new FileInputStream(sourceFile));
+read(): int Reads the next byte of data from the input stream. The value byte is returned as
an int value in the range 0 to 255. If no byte is available because the end of
the stream has been reached, the value –1 is returned.
+read(b: byte[]): int Reads up to b.length bytes into array b from the input stream and returns the
actual number of bytes read. Returns -1 at the end of the stream.
+read(b: byte[], off: int, Reads bytes from the input stream and stores into b[off], b[off+1], …,
len: int): int b[off+len-1]. The actual number of bytes read is returned. Returns -1 at the
end of the stream.
+available(): int Returns the number of bytes that can be read from the input stream.
+close(): void Closes this input stream and releases any system resources associated with the
stream.
+skip(n: long): long Skips over and discards n bytes of data from this input stream. The actual
number of bytes skipped is returned.
+markSupported(): boolean Tests if this input stream supports the mark and reset methods.
+mark(readlimit: int): void Marks the current position in this input stream.
+reset(): void Repositions this stream to the position at the time the mark method was last
called on this input stream.
60
Object I/O
DataInputStream/DataOutputStream enables you to perform I/O
for primitive type values and strings.
ObjectInputStream/ObjectOutputStream enables you to perform
I/O for objects in addition for primitive type values and strings.
FileInputStream
DataInputStream
InputStream FilterInputStream
BufferedInputStream
ObjectInputStream
Object
FileOutputStream BufferedOutputStream
ObjectOutputStream PrintStream
61
ObjectInputStream
java.io.InputStream ObjectStreamConstants
java.io.DataInput
java.io.ObjectInputStream java.io.ObjectInput
62
ObjectOutputStream
java.io.OutputStream ObjectStreamConstants
java.io.DataOutput
java.io.ObjectOutputStream java.io.ObjectOutput
63
Using Object Streams
You may wrap an ObjectInputStream/ObjectOutputStream on any
InputStream/OutputStream using the following constructors:
// Create an ObjectInputStream
public ObjectInputStream(InputStream in)
// Create an ObjectOutputStream
public ObjectOutputStream(OutputStream out)
TestObjectOutputStream
Run
TestObjectOutputStream Run
TestObjectInputStream
Run
TestObjectInputStream Run
import java.io.*;
12345
John Susan Kim
The Serializable Interface
• Not all objects can be written to an output stream. Objects that can
be written to an object stream is said to be serializable. A serializable
object is an instance of the java.io.Serializable interface. So the class
of a serializable object must implement Serializable.
• The Serializable interface is a marker interface. It has no methods, so
you don't need to add additional code in your class that implements
Serializable.
• Implementing this interface enables the Java serialization mechanism
to automate the process of storing the objects and arrays.
The Serializable Interface
• To appreciate this automation feature, consider what you otherwise need
to do in order to store an object. Suppose that you wish to store an
ArrayList object. To do this, you need to store all the elements in the list.
• Each element is an object that may contain other objects. As you can see,
this would be a very tedious process. Fortunately, you don’t have to go
through it manually.
• Java provides a built-in mechanism to automate the process of writing
objects. This process is referred as object serialization, which is
implemented in ObjectOutputStream. In contrast, the process of reading
objects is referred as object deserialization, which is implemented in
ObjectInputStream.
The Serializable Interface
• Many classes in the Java API implement Serializable. All the wrapper
classes for primitivetype values, java.math.BigInteger,
java.math.BigDecimal, java.lang.String, java.lang.StringBuilder,
java.lang.StringBuffer, java.util.Date, and java.util.ArrayList implement
java.io.Serializable.
• Attempting to store an object that does not support the Serializable
interface would cause a NotSerializableException.
• To make the object is Serializable , its class must
implement the Serializable interface
• Note that the in Java static field are not serialized and The values of the
object’s static variables are not stored..
The transient Keyword
• If an object is an instance of Serializable, but it contains non-
serializable instance data fields, can the object be serialized?
• The answer is no. To enable the object to be serialized, you can use
the transient keyword to mark these data fields to tell the JVM to
ignore these fields when writing the object to an object stream.
The transient Keyword
• When we de-serialized an object only, instance variables are saved
and will have same values after the process.
• Transient variables − The values of the transient variables are never
considered (they are excluded from the serialization process). i.e.
When we declare a variable transient, after de-serialization its value
will always be null, false, or, zero (default value).
• Static variables − The values of static variables will not be preserved
during the de-serialization process. In-fact static variables are also not
serialized but since these belongs to the class. After de-serialization
they get their current values from the class.
The transient Keyword, cont.
Consider the following class:
When an object of the Foo class is serialized, only variable v1 is serialized. Variable
v2 is not serialized because it is a static variable, and variable v3 is not serialized
because it is marked transient. If v3 were not marked transient, a
java.io.NotSerializableException would occur.
class Student implements Serializable{
public void setAge(int age) {
private String name;
this.age = age;
private transient int age;
}
private static int year = 2018;
public void setYear(int year) {
public Student(){
Student.year = year;
System.out.println("This is a constructor");
}
this.name = "Krishna";
}
this.age = 25;
}
public Student(String name, int age){
this.name = name;
this.age = age;
}
public void display() {
System.out.println("Name: "+this.name);
System.out.println("Age: "+this.age);
System.out.println("Year: "+Student.year);
}
public void setName(String name) {
this.name = name;
}
public class SerializeExample{
public static void main(String args[]) throws Exception{
Student std = new Student("Vani", 27);
//Serializing the object
FileOutputStream fos = new FileOutputStream("e:\student.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(std);
oos.close(); fos.close();
//Printing the data before de-serialization
System.out.println("Values before de-serialization");
std.display();
std.setYear(2019); //Changing the static variable value
std.setName("Varada"); //Changing the instance variable value
std.setAge(19); //Changing the transient variable value
System.out.println("Object serialized.......");
//De-serializing the object
FileInputStream fis = new FileInputStream("e:\student.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Student deSerializedStd = (Student) ois.readObject();
System.out.println("Object de-serialized.......");
ois.close(); fis.close();
System.out.println("Values after de-serialization");
deSerializedStd.display();
}}
Output
After the process the value of the
• Values before de-serialization: instance variables will be same. The
• Name: Vani transient variables display the default
• Age: 27 values, and the static variables print
the new (current) value from the
• Year: 2018 class.
• Object serialized.......
• Object de-serialized.......
• Values after de-serialization:
• Name: Vani
• Age: 0
• Year: 2019
Serializing Arrays
• An array is serializable if all its elements are serializable. So an entire
array can be saved using writeObject into a file and later restored
using readObject. Here is an example that stores an array of five int
values and an array of three strings, and reads them back to display
on the console.
TestObjectStreamForArray
Run
TestObjectStreamForArray Run
import java.io.*;
public class TestObjectStreamForArray {
public static void main(String[] args)
throws ClassNotFoundException, IOException {
int[] numbers = {1, 2, 3, 4, 5};
String[] strings = {"John", "Susan", "Kim"};
try ( // Create an output stream for file array.dat
ObjectOutputStream output = new ObjectOutputStream(new
FileOutputStream("array.dat", true));
) {
// Write arrays to the object output stream
output.writeObject(numbers);
output.writeObject(strings);
}
try ( // Create an input stream for file array.dat
ObjectInputStream input =new ObjectInputStream(new FileInputStream("array.dat"));
) {
int[] newNumbers = (int[])(input.readObject());
String[] newStrings = (String[])(input.readObject());
// Display arrays
for (int i = 0; i < newNumbers.length; i++)
System.out.print(newNumbers[i] + " ");
System.out.println();
for (int i = 0; i < newStrings.length; i++)
System.out.print(newStrings[i] + " ");
}
}
}
Reimplementing The Case study in Slide 18 but
using Binary Objects
public class FileMangerBinary implements Serializable {
public boolean write(String FilePath, Object data) {
try { FileManger Class
System.out.print("\nwritting in ! " + FilePath);
writter.writeObject(data);
} catch (IOException e) {
System.out.println("Can't write ...!\n" + e);
} Go To text Version
Go To text Version
Go To text Version
Random Access Files
• All of the streams you have used so far are known as read-only or
write-only streams.
• The external files of these streams are sequential files that cannot be
updated without creating a new file.
• It is often necessary to modify files or to insert new records into files.
• Java provides the RandomAccessFile class to allow a file to be read
from and write to at random locations.
RandomAccessFile
83
RandomAccessFile
• A random access file consists of a sequence of bytes. There is a
special marker called file pointer that is positioned at one of these
bytes.
• A read or write operation takes place at the location of the file
pointer. When a file is opened, the file pointer sets at the beginning of
the file.
• When you read or write data to the file, the file pointer moves
forward to the next data.
• For example, if you read an int value using readInt(), the JVM reads
four bytes from the file pointer and now the file pointer is four bytes
ahead of the previous location.
File Pointer
RandomAccessFile Methods
• Many methods in RandomAccessFile are the same as those in
DataInputStream and DataOutputStream. For example,
readInt(), readLong(), writeDouble(), readLine(),
writeInt(), and writeLong() can be used in data input
stream or data output stream as well as in RandomAccessFile
streams.
RandomAccessFile Methods, cont.
void seek(long pos) throws IOException;
Sets the offset from the beginning of the RandomAccessFile
stream to where the next read
or write occurs.
RandomAccessFile raf =
new RandomAccessFile("test.dat", "r"); // read
only
A Short Example on RandomAccessFile
TestRandomAccessFile
Run
TestRandomAccessFile Run
import java.io.*;
• This slides based on slides provided by Introduction to Java Programming and Data Structures,
Comprehensive Version 12th Edition, by Y. Liang (Author), Y. Daniel Liang
• © Copyright 1992-2012 by Pearson Education, Inc. All Rights Reserved.
• php - What is the advantage of using try {} catch {} versus if {} else {} - Stack Overflow