5 Breakpoints
A breakpoint is a program interruption point. Its goal is to interrupt the program at a specific point. So if we place a breakpoint somewhere in the source code of the program, the application will stop juste before executing this command.
An important note is that a breakpoint can only be placed on a statement. For example, variable declarations are not statements (they only say that a variable will exist, but the program does not perform any "operation" regarding this code. On the other side, if a value assignment is a part of variable declaration, it is already a valid statement (the operation is "assigning a value to a variable").
int a; // not a statement
int b = 0; // is a statement
Similarly, method declarations/headers are not statements. However, the body of methods typically contains commands:
public String getA(){ // not a statement, but a breakpoint can be placed here
String ret; // not a statement
ret = "A"; // is a statement
return ret; // is a statement
} // not a statement
Note that although the method signature line is not a statement, you can place a breakpoint here. Once set, the environment will automatically place a breakpoint on the first statement line of the method.
Basic Breakpoint Operations
A breakpoint can be placed in two simple ways:
Ctrl+F8 on a specific line
By clicking on the desired line in the line header before the line number (gray column).

The purple circle shows where to click to insert a breakpoint. Insertion of a breakpoint is reflected by coloring the line with a reddish color and a circle icon of the same color. The following figure shows the insertion of a breakpoint on all command lines.

In the figure, you can notice:
At line 10 - It was mentioned above that a breakpoint cannot be placed on a method declaration. However, Idea allows you to prepare a breakpoint here. At startup, the breakpoint is not placed here, but placed at the first statement of the method and the run is interrupted once the method is called. This state is represented by a change in icon - a reddish diamond (instead of a circle).
At line 11 - As mentioned, a variable declaration is not a statement. Therefore, you cannot set the breakpoint here. Or, more precisely - you can set a breakpoint here; however, once executed, the invalid breakpoints are ignored and represented by the respective icon (see lines 11 or 14).
At line 14 - You cannot defined a breakpoint at the method end. To do so, you need to place a breakpoint at the
return
statement.
Removing a breakpoint is done in the same way as adding one.
Example
A demonstration of behavior follows. Let's have the following simple code in the main() method.
public static void main(String[] args) {
int a = 5;
int b = 7;
int c = a + b;
System.out.println(c);
}
The method adds two numbers and prints the result. We place a breakpoint on the addition line.

Now let's run the application.
If we start the application classically – F6 – without debug mode, the application will run to the end, it will terminate and the sum statement obtained by line 13 – i.e. the value 12 – will appear on the console.
However, if we start the application in debug mode - Ctrl+F5, the application will start in DebugRun mode and then gets interrupted in Stepping mode (see next chapter) on line 12 after reaching the breakpoint. This will be signaled by a blue colored line:

The blue-colored line says that the application is in a suspended state, in stepping debugging mode. The highlighted line indicates a command that is yet to be executed.
In the stepping mode, you can dynamically add or remove additional breakpoints to the application: just place (or remove) them again.
To resume the application run from suspended mode, use F9 key or the green arrow in the Debug toolbar:

Another example
If we place two breakpoints in the program, the application will stop when the first one is reached. Consider a program that generates an array of numbers and then sums them. Finally it prints the result.
public static void main(String[] args) {
double [] data = new double[1_000_000]; // 1. BP
for (int i = 0; i < data.length; i++) {
data[i] = Math.random();
}
double sum = 0; // 2. BP
int index = 0;
for (int i = 0; i < data.length; i++) {
sum += data[i];
}
System.out.println("Result is " + sum);
}
Place two breakpoints in the program and then start the program. The program first stops at the first breakpoint.

If the programmer now wants to continue the calculation, he presses the F9 key and the program runs until it hits the second breakpoint:

If the programmer now starts the program again, the program will reach the end (because there is no more breakpoint in the run path) and will exit.
General rules using breakpoints for transitions between debug-run and stepping states can be subsequently formulated as follows. If the programmer starts a program in debug-run mode, the program will run in this mode until:
does not end (by successfully completing the program);
there is no fatal error in the application terminating the running of the application (unsuccessful termination of the program);
does not encounter a breakpoint (switches to the stepping state).
At the end, lets mention specific breakpoint locations:
You can place a single-hit breakpoint using Alt+Click. This breakpoint is removed once hit.
You can place a breakpoint at the method header to capture method entrance.
You can place a breakpoint at the class declaration line to suspend the code when default constructor is called.
You can place a breakpoint at the field (variable) of the class. Then, this breakpoint will suspend the code when the variable value is being updated.
Using a breakpoint to monitor the application's progress
Breakpoints are primarily used to stop an application from running at a certain point. The programmer can then monitor the variables at this point or browse the application continuously (it will be explained in the next chapters).
Conditional commands – if, switch
However, the programmer can also use breakpoints to monitor the progress of the code. An illustrative example can be a simple code snippet with an "if-else" statement.

If the programmer places breakpoints in both branches, after starting the application, it must necessarily (that is, if the program passes through the condition on line 9) reach one of these branches. Depending on which of the branches the program stops, the programmer can determine whether the above condition has been evaluated as true or false.

So in the example above, the condition was not met, the value of a
was less than or equal to 10, and the program execution jumped to line 12.
Function calls
In a similar way, for example, you can test whether the created function is called. In this way, the programmer can easily find out whether he forgot to call a certain function (or, using other mechanisms, find out where the function was called from). It is enough if the programmer inserts a breakpoint into the function somewhere (ideally at the beginning). If the application stops at a breakpoint, the program calls the given function. If the application does not stop at the breakpoint, the function is not called (or the application terminates with an error before the function is called).
Iterations
Breakpoints can also be used in iterations. It is important to note that a breakpoint is hit repeatedly in in every iteration!

In this case, after starting, the application will be stopped at line 5 in the first iteration (when i
is 0), after restart (F9) in the second iteration (when i
is 1), etc. This breakpoint will therefore be encountered in each iteration; in total, the program stops here 1,000,000 times.
Breakpoint properties
Certain behavior can also be set to the created breakpoint through its properties.
Breakpoint conditions
As mentioned, when running an application in debug-run mode, the application will always stop when a breakpoint is reached.
However, sometimes, typically in cycles, such processing is disadvantageous. Consider the following example where we are checking data read from a large text file.
int linesCount = getLinesCount();
for (int i = 0; i < linesCount; i++) {
String line = readLineFromFile();
double d = convertLineToDouble(line);
data.add(d);
}
In this case, we know how many lines there are in the file (for example, 10,000). However, one line of this large file ends up with an error when calling the convertLineToDouble(line)
method. When executed, the code returns an error:
Exception in thread "main" java.lang.RuntimeException: Invalid data.
at breakpoints.Program.convertLineToDouble(ToDelete58432.java:58)
at breakpoints.Program.main(ToDelete58432.java:32)
Java Result: 1
However, this error only says that the data is not correct, but does not say what data at all. The programmer would need to find out which are the erroneous data, and most importantly, on which line of the input file they appear.
Now, if the programmer tries to find the error, he must place a breakpoint in the loop handling the reading from the file:

The programmer can now check the value in the variable d (it will be explained in the following chapters) as well as see what line of the file it is on (this is shown in the variable i). But since we said that the file has 10,000 lines, it may happen that the very first line is not the one with the error. Therefore, if the programmer restarts the application (F5), one turn of the cycle is performed, and in the next turn of the cycle, the application stops again at a breakpoint:

One can notice the difference from stopping at the breakpoint in the previous case - there is no difference. The program simply stops at a breakpoint every time, every iteration. So the programmer can now repeatedly run the program (F9) and perform more and more iterations. When a certain iteration fails and the program crashes, then the programmer will be on the wrong line. If he knows the iteration number, he can look in the source file and see what the problem line of the input file contains.
But repeatedly pressing the F9 key will not help the programmer - what if the error is as far as line 8,574? Such checking and gradually going through 8 thousand iterations of the cycle would be time consuming and mentally draining. Fortunately, the programmer can help with the technique of conditional breakpoints.
A programmer can define a condition - once this condition is true, the breakpoint is hit and a program is suspended. If the condition is false, the breakpoint is skipped.
The breakpoint condition is defined on the breakpoint context menu (see figure). The Properties window opens.

There is a Condition text box in the breakpoint properties window. Here you can now specify any condition indicating when the breakpoint should stop. If we are in the for cycle and we want to stop, if the control variable also has the value 7, all we have to do is enter:

Attention! This is a value evaluating conditions, so the rules apply
The condition does not end with a semicolon.
Conditions can be chained arbitrarily (as if, for example, you would write the condition in the parentheses of the if statement, i.e.
(a > 7 && a < 10) || b = 3
.For comparison, the comparison sign must be used correctly (two equals:
a == b
). They don't forget to use the functionx.equals(y)
to compare strings or when necessary.
If a condition is set on a breakpoint, the breakpoint will change its icon:

Using this knowledge and the technique of bisecting intervals, the problem of finding a wrong iteration in a cycle can be easily solved.
Enabled/Disabled breakpoints
Sometimes it is advisable not to delete the breakpoint directly, but only to turn it off for a while and turn it on again later. Both can be done again via the context menu of the breakpoint and the Enabled option.

Once the breakpoint is disabled, it cannot be hit. However, you can re-enable the breakpoint at any time.
This is useful if you have a breakpoint with a condition or other additional settings. By deleting/reseting the breakpoint, you have to set the settings again. By disabling/enabling the breakpoint, you preserve the settings.
Additional breakpoint settings
Using the More... button, you can expand full breakpoint settings. Then, you can adjust several other properties. The most significant are explained in the table below.

Enabled
Enabled breakpoint can be hit. Disabled breakpoint preservers its configuration, but cannot be hit.
Suspend
Defines, how the suspendation behaves in multithreaded environment. All - means all application threads are suspended. Thread - means only the thread hitting the breakpoint is suspended.
Log ...
Prints a log (message) into the console window when the breakpoint is hit.
Log "Breakpoint hit" message
Logs a message only saying that the breakpoint was hit.
Log Stack trace
Logs a full stack trace when a breakpoint is hit. Stack trace is explained later in this course.
Evaluate and log
By setting a custom text in the text field, you can print a custom log message to a console. This message can also contain a value of variables or a result of a function calls.
Remove once hit
Breakpoint is removed once it is hit. Therefore, the breakpoint is always hit only once.
Pass count
You can specify a count, how many times a breakpoint is run through until its hit.
Instance/Class/Caller filters
You can specify, which instance/class/caller can invoke the breakpoint. More advanced technique.
Exception as a breakpoint
Very powerful feature in Idea (and some other development environments) is handling exceptions as breakpoints.
Why? If an exception occures in the application, it causes imminent application crash. Once the application has crashed, you have only a limited tools to diagnose why and when did the application crash. On the other side, if an exception is handled as a breakpoint, the application run is suspended in the case of exception. It means, you have the application calculation frozen in the moment of exception invocation. You can analyse stack trace, variable values and other important properties (see the following chapters).
In general Idea is set to handle any exception as a breakpoint. You can adjust this behavior using Breakpoints window, in the section Java Exception Breakpoints - see the left side of the following image.

You can add a custom exception-breakpoint handling using the +
button in the top left corner. Morever, for every exception-breakpoint, you can adjust the similar properties as above; moreover, you can distinquish between caught and uncaught exception handling.
Again note, that exception-breakpoint handling is available only in the application Debug-Run state.
Exception window
To overview and simple adjust all the breakpoints in the current project, use the Breakpoint window.
This window can be opened using "Run -> View Breakpoints" menu, from the Debug bottom menu and the breakpoints icon, or by a key shortcut Ctrl+Shift+F8 (by default).
Interrupting calculations
Sometimes there is a situation where the current program needs to be suspended at the current point of the calculation, even though we do not have a breakpoint at that point. Typically, it is at times when the program performs some complex, longer-lasting calculation, and the programmer wants to find out, for example, what state the calculation is in, if the program continues correctly, or if there is an error somewhere in the program.
At such a moment, the programmer can pause the program using the toolbar and the pause icon.

When the program is suspended, the application is interrupted wherever the current calculation is performed and marks the next example to be executed. The difference from a breakpoint is that a breakpoint determines the exact line where the program should stop, while a pause stops the program wherever it is.
Last updated