2

I've noticed that when using scanners, if I want to set attributes such as delimiter or locale, the methods to do so return the Scanner object itself:

public Scanner useDelimiter(String pattern) {
    modCount++;
    delimPattern = patternCache.forName(pattern);
    return this;
}

What I don't understand is that, if the attribute is changed (instead of it creating a new object), why does it return a Scanner object instead of void? It's not like I have to store the return value inside a variable - in fact, if I try to do so, like in the code below, Eclipse will give the message Resource leak: 'lineScanner' is not closed at this location:

Scanner scanner = new Scanner(new File("accounts.csv"));
String line;
    
while(scanner.hasNextLine()) {
    line = scanner.nextLine();
    Scanner lineScanner = new Scanner(line);
    lineScanner = lineScanner.useDelimiter(",");
    ...
}
  • 2
    Because that way you can call multiple functions in the same line. ``scanner.a().b()`` It's for convenience. – new Q Open Wid Jul 18 '22 at 15:13
  • it's called method chaining. Related: [Method chaining - why is it a good practice, or not?](https://stackoverflow.com/questions/1103985/method-chaining-why-is-it-a-good-practice-or-not) – jhamon Jul 18 '22 at 15:14
  • 1
    See [fluent interface](https://en.wikipedia.org/wiki/Fluent_interface). Some people don't like it nowadays, but it has its proponents. – Silvio Mayolo Jul 18 '22 at 15:14

1 Answers1

5

This is more for convenience than anything else. The return value can be ignored; it just allows you to chain methods for readability.

E.g.

lineScanner.useDelimiter(",").useLocale(Locale.US).useRadix(10);

This is more readable and shorter than

lineScanner.useDelimiter(",");
lineScanner.useLocale(Locale.US);
lineScanner.useRadix(10);
anut
  • 481
  • 1
  • 11
  • Your answer is correct but I would argue the readability reason. Imo, the second is more readable, the first is more of a shorthand for doing the same. – WJS Jul 18 '22 at 16:15