Skip to content
Java networking 5 min read

URL Class

Java’s URL class (in the java.net package) represents a Uniform Resource Locator — the familiar address that points to a resource on the internet or a local network. With it you can parse URL components, open a connection, and read remote content without reaching for any third-party library.

What Is a URL?

A URL has several distinct parts. Take https://example.com:8080/path/page.html?q=java#section:

ComponentValueGetter method
ProtocolhttpsgetProtocol()
Hostexample.comgetHost()
Port8080getPort()
Path/path/page.htmlgetPath()
Queryq=javagetQuery()
Ref (anchor)sectiongetRef()

The URL class parses all of this for you automatically.

Creating a URL Object

The constructor throws a checked MalformedURLException, so you must handle it.

import java.net.MalformedURLException;
import java.net.URL;

public class CreateURL {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("https://example.com:8080/path/page.html?q=java#section");

        System.out.println("Protocol : " + url.getProtocol());
        System.out.println("Host     : " + url.getHost());
        System.out.println("Port     : " + url.getPort());
        System.out.println("Path     : " + url.getPath());
        System.out.println("Query    : " + url.getQuery());
        System.out.println("Ref      : " + url.getRef());
        System.out.println("File     : " + url.getFile()); // path + query
    }
}

Output:

Protocol : https
Host     : example.com
Port     : 8080
Path     : /path/page.html
Query    : q=java
Ref      : section
File     : /path/page.html?q=java

Note: getPort() returns -1 if no port is specified. Use getDefaultPort() to get the protocol’s default (e.g., 443 for HTTPS).

Reading Content with openStream()

The quickest way to fetch remote content is openStream(), which returns an InputStream you can wrap in a BufferedReader.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

public class ReadURL {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://example.com");

        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(url.openStream()))) {

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }
    }
}

openStream() is shorthand for openConnection().getInputStream(). It works well for simple GET reads but gives you no control over headers or timeouts. For that, step up to URLConnection or HttpURLConnection.

Tip: Always use try-with-resources so the stream closes even if an exception occurs — network streams hold OS-level sockets.

Constructing a URL from Parts

You can build a URL from separate components to avoid manually concatenating strings and escaping characters.

import java.net.MalformedURLException;
import java.net.URL;

public class URLFromParts {
    public static void main(String[] args) throws MalformedURLException {
        // URL(String protocol, String host, int port, String file)
        URL url = new URL("https", "api.example.com", 443, "/v1/users?active=true");
        System.out.println(url.toString());
    }
}

Output:

https://api.example.com:443/v1/users?active=true

There is also a two-argument constructor URL(URL context, String spec) that resolves a relative URL against a base URL — handy when parsing href attributes from HTML.

import java.net.MalformedURLException;
import java.net.URL;

public class RelativeURL {
    public static void main(String[] args) throws MalformedURLException {
        URL base = new URL("https://example.com/docs/");
        URL resolved = new URL(base, "../images/logo.png");
        System.out.println(resolved); // https://example.com/images/logo.png
    }
}

Converting Between URL and URI

URL and URI are related but different. URI is a stricter syntactic concept (it can be relative, opaque, or absolute), while URL always refers to a locatable resource. You often need to convert between them when working with modern APIs like HttpClient.

import java.net.URI;
import java.net.URL;

public class URLtoURI {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://example.com/path?q=java");

        // URL → URI
        URI uri = url.toURI();
        System.out.println(uri.getScheme()); // https

        // URI → URL
        URL back = uri.toURL();
        System.out.println(back.getHost()); // example.com
    }
}

Warning: URL.equals() and URL.hashCode() can perform a DNS lookup to compare hosts. This makes them slow and potentially unreliable in offline environments or inside HashMap/HashSet. Prefer URI for equality checks and use URL only when you actually need to open a connection.

Downloading a File

Combining openStream() with a FileOutputStream lets you download binary files.

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;

public class DownloadFile {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://example.com/sample.pdf");

        try (InputStream in = url.openStream();
             FileOutputStream out = new FileOutputStream("sample.pdf")) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
            System.out.println("Download complete.");
        }
    }
}

Under the Hood

When you call new URL(...), Java delegates protocol handling to a URLStreamHandler. Each protocol (http, https, ftp, file, jar…) has its own handler registered in the sun.net.www.protocol package. The handler is resolved by URL.getURLStreamHandler(protocol) — you can even plug in a custom protocol by registering your own URLStreamHandlerFactory.

openStream() triggers these steps internally:

  1. URL.openConnection() asks the handler to create a URLConnection subclass (e.g., HttpURLConnection for http/https).
  2. URLConnection.connect() performs the TCP handshake and, for HTTPS, the TLS negotiation.
  3. getInputStream() wraps the socket’s raw input stream.

For HTTPS, Java uses the JVM’s default SSLContext, which trusts the standard CA bundle shipped with the JDK. If you need custom certificates, you configure a custom SSLContext and pass it to HttpsURLConnection. For anything beyond simple reads — headers, timeouts, redirects, authentication — use HttpURLConnection or the modern java.net.http.HttpClient introduced in Java 11 (see Java 11 Features).

Quick Method Reference

MethodReturnsDescription
getProtocol()StringProtocol (http, https, ftp…)
getHost()StringHostname
getPort()intPort or -1 if not set
getDefaultPort()intProtocol’s default port
getPath()StringPath component
getQuery()StringQuery string (after ?)
getRef()StringFragment (after #)
getFile()StringPath + query
openStream()InputStreamOpens a read-only stream
openConnection()URLConnectionReturns a configurable connection
toURI()URIConverts to a URI
toString()StringFull URL as a string

Note: The URL class has been part of Java since version 1.0, but in Java 20+ it was formally deprecated in favour of URI for parsing purposes. The class still works fine for opening connections; the deprecation targets uses like equality checks that were always problematic.

Last updated June 13, 2026
Was this helpful?