When I debug an app, in the debug tool window there is a Watches window. I have read this manual over and over, but cannot find any practicle usage of Watches.
Somehow, I think this is a cool and useful tool and I lack from not using it.
Can someone explain when should I use it and give a few samples? Ideally, the description will be bound to a concrete (imaginary) situation so that I better apply it in my work.
The debugger watches a variable through the content of a storage address, computed at the time the watch condition is set. When the content at the storage address is changed from the value it had when the watch condition was set or when the last watch condition occurred, a breakpoint is set, and the program stops.
Select the desired item in the Variables pane and drag it to the Watches pane. Select a variable or expression in the editor and then drag it to the Watches pane or right-click it and choose Add to Watches.
This section allows you to define expressions which you'd like to see how they evolve/change with every step of your debug process, without manually inspecting all the available objects and their properties. Let's take the following simple sample which intentionally throws a NullPointerException (NPE):
public class WatchSample {
static class Student {
public static final int CREDITS_REQUIRED_FOR_GRADUATION = 10;
private String name;
private Integer credits;
public Student(String name, Integer credits) {
this.name = name;
this.credits = credits;
}
String getName() {
return name;
}
public boolean hasGraduated() {
return credits >= CREDITS_REQUIRED_FOR_GRADUATION;
}
public Integer getCredits() {
return credits;
}
}
public static void main(String[] args) throws Exception {
List<Student> students = simulateReadingFromDB();
for (Student student : students) {
if (student.hasGraduated()) {
System.out.println("Student [" + student.getName() + "] has graduated with [" + student.getCredits() + "] credits");
}
}
}
private static List<Student> simulateReadingFromDB() {
List<Student> students = new ArrayList<>(3);
students.add(new Student("S1", 15));
students.add(new Student("S2", null)); // <- simulate some mistake
students.add(new Student("S3", 10));
return students;
}
}
At some point in time you may wonder how come you get a NPE and what needs fixing. So just set a breakpoint, add a few watches and carefully step through the lines. Eventually you'll end up with the troublemaker in sight:
Of course this is a basic example and should be taken as such. Within a regular app you'll probably have more complex scenarios and expressions you'd like to inspect, and this will make more sense, for example: if (((position > 0 && position < MAX) || (position < 0 && position > MIN) && (players(currentPlayer).isNotDead() && move.isAllowed()) && time.notUp())....
. In this case you can evaluate the sub-expressions to see which one returns false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With