Course – LS (cat=REST)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:


1. Overview

When we try to access some resources in the network, we must first obtain the resource's Uniform Resource Identifier (URI).

The Java standard library provides the URI class, allowing us to handle URIs more easily. Of course, to use the URI class, the first step is to get a URI instance.

Let's say we have the address string of some resource in the network. There are two ways to get a URI instance:

  • calling the constructor with the address string directly – URI myUri = new URI(theAddress);
  • calling the URI.create() static method – URI myUri = URI.create(theAddress);

In this quick tutorial, we'll take a closer look at these two approaches and discuss their differences.

2. Using the URI Constructor

First, let's have a look at the constructor's signature:

public URI(String str) throws URISyntaxException

As we can see, calling the constructor with an invalid address may raise URISyntaxException. To make it simple, let's create a unit test to see this case:

assertThrows(URISyntaxException.class, () -> new URI("I am an invalid URI string."));

We should note that URISyntaxException is a subclass of Exception:

public class URISyntaxException extends Exception { ... }

Therefore, it's a checked exception. In other words, when we call this constructor, we must handle the URISyntaxException:

try {
    URI myUri = new URI("");
} catch (URISyntaxException e) {

We've seen the constructor usage and the exception handling as a unit test. If we execute the test, it passes. However, the code doesn't compile without the try-catch.

As we can see, creating a URI instance using the constructor is pretty straightforward. Next, let's move to the URI.create() method.

3. Using the URI.create() Method

We've mentioned URI.create() can create a URI instance as well. To understand the difference between the create() method and the constructor, let's look at the create() method's source code:

public static URI create(String str) {
    try {
        return new URI(str);
    } catch (URISyntaxException x) {
        throw new IllegalArgumentException(x.getMessage(), x);

As we can see in the code above, the create() method's implementation is pretty simple. First, it invokes the constructor directly. Further, if URISyntaxException is thrown, it wraps the exception in a new IllegalArgumentException. 

So next, let's create a test to see if we can get the expected IllegalArgumentException, if we feed create() an invalid URI string:

assertThrows(IllegalArgumentException.class, () -> URI.create("I am an invalid URI string."));

The test passes if we give it a run.

If we take a closer look at the IllegalArgumentException class, we can see it's a subclass of RuntimeException:

public class IllegalArgumentException extends RuntimeException { ... }

We know that RuntimeException is an unchecked exception. This means when we create a URI instance using the create() method, we don't have to handle the exception in an explicit try-catch:

URI myUri = URI.create("");

Therefore, the main difference between create() and the URI() constructor is the create() method changes the constructor's checked exception (URISyntaxException) into an unchecked exception (IllegalArgumentException).

If we don't want to deal with the checked exception, we can use the create() static method to create the URI instance.

5. Conclusion

In this article, we've discussed the difference between instantiating a URI object using the constructor and the URI.create() method.

As usual, all code snippets presented here are available over on GitHub.

Course – LS (cat=REST)

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course :

res – REST (eBook) (cat=REST)
Inline Feedbacks
View all comments
Comments are closed on this article!