Day 09 - Debugging
Day 09 - Debugging
Notice
❑ You will get Fahrenheit 67 degrees, which is wrong. It should be 95.0. In Java, the division for integers is
the quotient - the fractional part is truncated - so in Java 9 / 5 is 1. To get the correct result, you need to
use 9.0 / 5, which results in 1.8.
That’s all three types of errors, but…
19
20
❖ Introduction to Bugs
❖ Syntax Errors
❖ Runtime Errors
❖ Logic Errors
❖ Exceptions Handling
❖ Debugging Strategies
❖ Final Touches
Exceptions Handling 21
❖ An exception is an object that’s created when an error occurs in a Java program and
Java can’t automatically fix it. The exception object contains information about the type
of error that occurred. However, the most important information - the cause of the error
- is indicated by the name of the exception class used to create the exception. You don’t
usually have to do anything with an exception object other than figure out which one
you have. Each type of exception that can occur is represented by a different exception
class.
❖ For example, here are some typical exceptions:
❑ IllegalArgumentException: You passed an incorrect argument to a method.
❑ InputMismatchException: The console input doesn’t match the data type expected by a method of
the Scanner class.
❑ ArithmeticException: You tried an illegal type of arithmetic operation, such as dividing an integer
by zero.
❑ IOException: A method that performs I/O encountered an unrecoverable I/O error.
❑ ClassNotFoundException: A necessary class couldn’t be found.
Exceptions Handling 22
❖ There are many other types of exceptions besides these. And, you might need to know a
few other things about exceptions (some were explained in lecture 06):
❑ When an error occurs and an exception object is created, Java is said to have thrown an
exception. Java has a pretty good throwing arm, so the exception is always thrown right
back to the statement that caused it to be created.
❑ The statement that caused the exception can catch the exception if it wants it. But it doesn’t
have to catch the exception if it doesn’t want it. Instead, it can duck and let someone else
catch the exception. That someone else is the statement that called the method that’s
currently executing.
❑ If everyone ducks and the exception is never caught by the program, the program ends
abruptly and displays a nasty looking exception message on the console.
❑ Two basic types of exceptions in Java are checked exceptions and unchecked exceptions:
➢ A checked exception is an exception that the compiler requires you to provide for it one
way or another. If you don’t, your program doesn’t compile.
➢ An unchecked exception is an exception that you can provide for, but you don’t have to.
Exceptions Handling 23
❖ As mentioned earlier, whenever you use a statement that might throw an exception, you should
write special code to anticipate and catch the exception. That way, your program won’t crash if
the exception occurs. You catch an exception by using a try-catch block:
try
{
// statements that can throw exceptions
}
catch (exception-type identifier)
{
// statements executed when exception is thrown
}
Exceptions Handling 24
❖ Here is a simple example:
try {
int c = 5 / 0;
} catch (Exception e) {
System.err.println("Exceptions: / by zero.");
}
Exceptions Handling 28
❖ As you can see, in most cases, the catch block of a try statement won’t do anything at all
with the exception object passed to it. However, you may occasionally want to display
an error message; exception objects have a few interesting methods that can come in
handy from time to time:
Example
try {
int c = a / b;
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
}
Exceptions Handling 29
❖ Now that we've explored how try-catch blocks allow us to handle exceptions, it’s also
important to ensure that certain actions always occur, whether an exception is thrown or
not. In Java, the finally block guarantees that, regardless of what happens inside the try
or catch blocks, critical cleanup operations will always be executed. This is particularly
useful when dealing with tasks like closing files, releasing resources, or closing database
connections.
try {
// statements that can throw exceptions
} catch (Exception-type identifier) {
// statements executed when exception is thrown
} finally {
// statements that are executed whether or not
exceptions occur
}
30
/**
* Converts a hex string into a decimal number and throws a
* NumberFormatException if the string is not a hex string
*/
public static int hexToDecimal(String hex) throws NumberFormatException {
int decimalValue = 0;
for (int i = 0; i < hex.length(); i++) {
if (!(hex.charAt(i) >= '0' && hex.charAt(i) <= '9') ||
!(hex.charAt(i) >= 'A' && hex.charAt(i) <= 'F'))
throw new NumberFormatException("String is not a hex string");
char hexChar = hex.charAt(i);
decimalValue = decimalValue * 16 + hexCharToDecimal(hexChar);
}
return decimalValue;
}
Exceptions Handling – Custom Exceptions 36
❖ You know, Java provides quite a few exception classes. Use them whenever possible
instead of defining your own exception classes. However, if you run into a problem that
cannot be adequately described by the predefined exception classes, you can create your
own exception class, derived from Exception or from a subclass of Exception, such as
IOException. For example:
//Custom Exception
class MyCustomException extends Exception {
public MyCustomException(String message) {
super(message);
}
}
38
39
Okay, so exceptions help catch Exactly! Logic errors are a bit sneaky because your
errors like runtime and code runs without any compile or runtime errors,
compile-time ones. But what but it doesn't behave as expected. The program
about logic errors? They seem might give the wrong results or behave
tricky because they don't cause unexpectedly. To catch these, you'll need to rely on
exceptions, right? debugging strategies, testing, or careful inspection
of your code's flow. Let’s see what can we do…
40
❖ Introduction to Bugs
❖ Syntax Errors
❖ Runtime Errors
❖ Logic Errors
❖ Exceptions Handling
❖ Debugging Strategies
❖ Final Touches
Debugging Strategies 41
❖ As mentioned, syntax errors are easy to find and easy to correct because the compiler
gives indications as to where the errors came from and why they are there. Runtime
errors are not difficult to find either, because the Java interpreter displays them on the
console when the program aborts. Finding logic errors, on the other hand, can be very
challenging.
❖ Logic errors are called bugs. The process of finding and correcting errors is called
debugging. A common approach to debugging is to use a combination of methods to
help pinpoint the part of the program where the bug is located. You can hand-trace the
program (i.e., catch errors by reading the program), or you can insert print statements in
order to show the values of the variables or the execution flow of the program. These
approaches might work for debugging a short, simple program, but for a large, complex
program, the most effective approach is to use a debugger utility.
Debugging Strategies 42
❖JDK includes a command-line debugger, jdb, which is invoked with a class name. jdb is
itself a Java program, running its own copy of Java interpreter. All the Java IDE tools,
such as Eclipse and NetBeans, include integrated debuggers. The debugger utilities let
you follow the execution of a program. They vary from one system to another, but they
all support most of the following helpful features.
❑ Executing a single statement at a time: The debugger allows you to execute one statement at a time
so that you can see the effect of each statement.
❑ Tracing into or stepping over a method: If a method is being executed, you can ask the debugger to
enter the method and execute one statement at a time in the method, or you can ask it to step over the
entire method. You should step over the entire method if you know that the method works. For
example, always step over system-supplied methods, such as System.out.println.
❑ Setting breakpoints: You can also set a breakpoint at a specific statement. Your program pauses when
it reaches a breakpoint. You can set as many breakpoints as you want. Breakpoints are particularly
useful when you know where your programming error starts. You can set a breakpoint at that
statement and have the program execute until it reaches the breakpoint.
Debugging Strategies 43
❖JDK includes a command-line debugger, jdb, which is invoked with a class name. jdb is
itself a Java program, running its own copy of Java interpreter. All the Java IDE tools,
such as Eclipse and NetBeans, include integrated debuggers. The debugger utilities let
you follow the execution of a program. They vary from one system to another, but they
all support most of the following helpful features.
❑ Displaying variables: The debugger lets you select several variables and display their values. As you
trace through a program, the content of a variable is continuously updated.
❑ Displaying call stacks: The debugger lets you trace all of the method calls. This feature is helpful
when you need to see a large picture of the program-execution flow.
❑ Modifying variables: Some debuggers enable you to modify the value of a variable when debugging.
This is convenient when you want to test a program with different samples but do not want to leave
the debugger.
Now that you have learned
Exceptions and Debugging.
Do you have any question?
If you don’t, in the next
section, I will show the
summary of this lecture...
Summary 45
1. Exception handling enables a method to throw an exception to its caller.
2. A Java exception is an instance of a class derived from java.lang.Throwable. Java
provides a number of predefined exception classes, such as Error, Exception,
RuntimeException, ClassNotFoundException, NullPointerException, and
ArithmeticException. You can also define your own exception class by
extending Exception.
3. Exceptions occur during the execution of a method. RuntimeException and
Error are unchecked exceptions; all other exceptions are checked.
4. When declaring a method, you have to declare a checked exception if the method
might throw it, thus telling the compiler what can go wrong.
5. The keyword for declaring an exception is throws, and the keyword for throwing
an exception is throw.
6. To invoke the method that declares checked exceptions, enclose it in a try
statement. When an exception occurs during the execution of the method, the
catch block catches and handles the exception.
Summary 46
7. If an exception is not caught in the current method, it is passed to its caller. The
process is repeated until the exception is caught or passed to the main method.
8. Various exception classes can be derived from a common superclass. If a catch
block catches the exception objects of a superclass, it can also catch all the
exception objects of the subclasses of that superclass.
9. The order in which exceptions are specified in a catch block is important. A
compile error will result if you specify an exception object of a class after an
exception object of the superclass of that class.
10. When an exception occurs in a method, the method exits immediately if it does
not catch the exception. If the method is required to perform some task before
exiting, you can catch the exception in the method and then rethrow it to its caller.
This brings us to the
end of this lecture!
It’s time for Final
Touches…
47
Final Touches 48
❖Introduction to Bugs
❑ “First actual case of bug being found.”
❑ The story goes that on September 9th, 1947, computer scientist Grace Hopper found a moth in the Harvard Mark
II computer’s log book and reported the world’s first literal computer bug. However, the term “bug”, in the sense
of technical error, dates back at least to 1878 and with Thomas Edison.
❑ On your programming journey, you are destined to encounter innumerable red errors. Some even say that
debugging is over 75% of the development time. But what makes a programmer successful isn’t avoiding errors;
it’s knowing how to find the solution.
❑ In Java, there are many different ways of classifying errors, but they can be boiled down to three categories:
1. Syntax errors: Errors found by the compiler.
2. Run-time errors: Errors that occur when the program is running.
3. Logic errors: Errors found by the programmer looking for the causes of erroneous results.
❑ Generally speaking, the errors become more difficult to find and fix as you move down the above list.
❑ In this section, we will be looking at different errors and different error messages, and we’ll teach you how to
think about errors in your code a little differently.
Final Touches 49
❖Syntax Errors
❑ When we are writing Java programs, the compiler is our first line of defense against errors. It can catch syntax
errors.
❑ Syntax errors represent grammar errors in the use of the programming language. They are the easiest to find and
correct. The compiler will tell you where it got into trouble, and its best guess as to what you did wrong.
❑ Some common syntax errors are:
1. Misspelled variable and method names
2. Omitting semicolons ;
3. Omitting closing parenthesis ), square bracket ], or curly brace }
❑ Here’s an example of a syntax error message:
Debug.java:5: error: ';' expected
int year = 2019
^
❑ Usually, the error is on the exact line indicated by the compiler, or the line just before it; however, if the problem
is incorrectly nested braces, the actual error may be at the beginning of the nested block.
Final Touches 50
❖Run-time Errors
❑ If our program has no compile-time errors, it’ll run. This is where the fun really starts.
❑ Errors which happen during program execution (run-time) after successful compilation are called run-time errors.
Run-time errors occur when a program with no compile-time errors asks the computer to do something that the
computer is unable to reliably do.
Thanks!
Any questions?
For an in-depth understanding of Java, I highly recommend
referring to the textbooks. This slide provides a brief overview
and may not cover all the details you're eager to explore!