Firstly, I am using Java v17 with Netbeans 12.6.

As I understood exceptions in Java, an exception has to either be thrown or handled.

However, I can't understand why this philosophy doesn't appear to be consistent within the Java core classes. For example, I had a code block similar to

      String s = "word 1,2,3";
      int firstComma = s.indexOf(",");
      int secondComma = s.indexOf(",", firstComma + 1);
      try {
        Long.parseLong(s.substring(firstComma + 1, secondComma));
      catch (Exception e) {
        System.out.println("Parsing error for " + s + "[" + firstComma + ", " + secondComma + "]: " + e.getMessage());

In Netbeans ( I assume as a result of the Java Compiler warnings), it reminds me that I can replace the 'Exception e' with named exceptions - perfect as this aids readability so accepting the recommendation, the line is amended to

However, the code can still fail with a StringIndexOutOfBoundsException, triggered by new String().substring() which calls String.checkBoundsBeginEnd() to check for illegal character offsets .

Checking the source, the substring() neither actions or throws this error and so I have to either
- Manually add the exception class to my list of exceptions (which Java accepts rather than saying is redundant), then I am left wondering if there are any other Exception classes that will slip through the try block.
- Revert back to 'Exception e', just to be safe and ignore the persistent warning to amend this.

Does anyone know why this anomaly occurs and if there are any others?

Also, apologies if this is a Netbeans specific issue - i.e. the offer to replace the generic Exception with Named Exceptions is local to the Netbeans environment rather than triggered by a warning in the Java compiler. If that is the case, I will use the NetBeans forum to look for help.

--- Update ---

I think that I have discovered the answer to my question, having found the following paragraph about a different exception class

ArithmeticException inherits from the RuntimeException class which means it is an unchecked, runtime exception [2]. This is due to a language design decision made to reduce the exception handling clutter that would otherwise arise with the high frequency of arithmetic operations, but more importantly because throwing and propagating arithmetic exceptions wouldn’t make sense for the majority of cases, which in practice are the result of logical programming errors that need to be refactored, rather than exceptions that need to be handled. Consequently, Java doesn’t require ArithmeticException instances to be checked and will only let them manifest at runtime.

As StringIndexOutOfBoundsException is also inherited from RuntimeException, it stands to reason that the only time that these can occur is by a coding error rather than expected from an external source and so are 'Silent' - as in not expected to happen.