JDK-8298224 : (fs) Re-visit Path.getExtension return value
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.nio
  • Priority: P3
  • Status: Closed
  • Resolution: Withdrawn
  • Fix Versions: 20
  • Submitted: 2022-12-06
  • Updated: 2022-12-07
  • Resolved: 2022-12-07
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Change `java.nio.file.Path::getExtension` to return a non-`null` string representing the file extension of the path's file name with the period separator character included.

Problem
-------

The present incarnation of `Path::getExtension` can return `null` in cases where no extension is found. This creates scenarios where `NullPointerException`s can become a problem. Not including the extension separator character in the extension also makes other path manipulations such as removing or replacing the extension somewhat more complex.

Solution
--------

Define the the path's file name's file extension to be that portion of the string representation of the file name after _and including_ the last period character as opposed to the portion of the file name string _after_ the last period. A returned empty string `""` instead of `null` now signifies that no extension was found, and a string containing only a single period character `"."` instead of solely an empty string `""` now signifies an empty extension.

Specification
-------------

    --- a/src/java.base/share/classes/java/nio/file/Path.java
    +++ b/src/java.base/share/classes/java/nio/file/Path.java
    @@ -257,53 +257,47 @@ public static Path of(URI uri) {
          * determined by the position of a period character ('.', U+002E FULL STOP)
          * within the file name string. If the file name element is {@code null},
          * or if the file name string does not contain a period character, or if
    -     * the only period in the file name string is its first character, then
    -     * the extension is {@code null}. Otherwise, the extension is the substring
    -     * after the last period in the file name string. If this last period is
    -     * also the last character in the file name string, then the  extension is
    -     * {@linkplain String#isEmpty empty}.
    +     * the only period in the file name string is its first character,  then
    +     * the extension is {@linkplain String#isEmpty empty}. Otherwise, the
    +     * extension is the substring starting with the last period in the file
    +     * name string. If this last period is also the last character in the file
    +     * name string, then the extension contains only a single period character.
    +     *
    +     * @apiNote
    +     * Unless no extension is found, in which case an empty string is returned,
    +     * the returned extension includes the period separator character. For
    +     * example, the extension which would be returned for a path with file name
    +     * "photograph.jpg" is ".jpg".
          *
          * @implSpec
          * The default implementation is equivalent for this path to:
          * <pre>{@code
          * int lastPeriod = fileName.lastIndexOf('.');
    -     * if (lastPeriod <= 0)
    -     *     return null;
    -     * return (lastPeriod == fileName.length() - 1)
    -     *     ? ""
    -     *     : fileName.substring(lastPeriod + 1);
    +     * return lastPeriod <= 0 ? return "" : fileName.substring(lastPeriod);
          * }</pre>
          *
    -     * @return  the file name extension of this path, which might be the
    -     *          empty string, or {@code null} if no extension is found
    +     * @return  the non-{@code null} file extension of this path's file name,
    +     *          possibly only a single period character, or an empty string if
    +     *          no extension is found
          *
          * @since 20
          */
         default String getExtension() {}