It seems to me your problem is name resolution.
InetAddress.getLocalHost() uses the local host name to do a name lookup against whatever nameserver(s) is/are listed in the local configuration. The result of the address returned is based on the DNS query performed using the hostname. If it's unable to resolve the hostname, it's going to return the first IP of the first adapter associated with the local host, which as far as I can tell is not really predictable. The first example should work, provided the host can resolve its own name to the address you consider to be the correct one.
In your second example binding a socket on port 80 to a remote host, the call to Socket.getLocalAddress() is going to return the local address the socket used to make the connection. It should only be using the loopback address to connect to the loopback address (i.e. 127.0.0.1 could not be used to connect to www.google.com because there would be no route to the host via the loopback address, unless you have some whacky localhost proxy setup going on). This method when used to connect to an Internet host, should reveal the IP address of the adapter that can get to the Internet because using the IP stack it's going to select the appropriate interface that has a route to the destination address. This is usually determined by a default gateway or static routes indicating which subnets are available out of which interfaces, although you can select the interface you want to use in certain constructor methods on the Socket class (which you aren't using in the example).
So, if the second example doesn't work - what hostname are you using to connect the socket to? Are you using the "www.w3c.org" hostname as in the example? If so, it should be doing a name lookup against the configured name servers to resolve www.w3c.org to an IP address, and then creating a socket and connecting it to the resolved IP on port 80. When it does this it will have to select the appropriate local interface, which should be the one that can route to the Internet. Then your call to s.getLocalAddress would return the IP address of that interface.
If on the other hand, you've entered the localhost, then you will get the result you received (provided it was able to actually connect to the local host on the port specified). If it wasn't able to connect, it should have thrown an error. But even then, it should only select the loopback if the loopback was specified -- In other words, if you entered "localhost", "127.0.0.1", or InetAddress.getByName(null).