Find free port in Java

Actually you output the port member that you specified in the constructor. So 0 is expected.
The javadoc states that the port will let the system pick up an ephemeral port for a binding operation. It doesn't tell that the port number will be valued with the ephemeral port directly in the InetSocketAddress instance. Actually you don't execute a binding operation with this InetSocketAddress instance.
In clear you didn't open/create a socket channel to communicate with this instance. So you cannot notice the result of the port.

For example this binds the a ServerSocket to a InetSocketAddress :

ServerSocket ss = new ServerSocket(..);
ss.bind(new InetSocketAddress(0));

Here is a more complete example illustrating how things work :

public class InetSockerAddressWithEphemeralPortMain {

    public static void main(String[] args) throws InterruptedException, IOException {
        InetSocketAddress randomSocketAddressFirst = new InetSocketAddress(0);

        try (ServerSocket ssOne = new ServerSocket()) {
            System.out.println("randomSocketAddress port before any binding : " + randomSocketAddressFirst.getPort());
            ssOne.bind(randomSocketAddressFirst);
            System.out.println("local port after first binding :" + ssOne.getLocalPort());
        }

        try (ServerSocket ssTwo = new ServerSocket()) {
            ssTwo.bind(randomSocketAddressFirst);
            System.out.println("local port after second binding :" + ssTwo.getLocalPort());
            System.out.println("randomSocketAddress port after all bindings : " + randomSocketAddressFirst.getPort());
        }

    }
}

Output :

randomSocketAddress port before any binding : 0

local port after first binding : 65110

local port after second binding : 65111

randomSocketAddress port after all bindings : 0

You can see that the InetSocketAddress object keeps always 0 as port value while the ServerSocket objects benefit from a picked up ephemeral port.