1. 概述

当我们试图访问网络中的某些资源时,首先需要获取资源的统一资源标识符(Uniform Resource Identifier,URI)。

Java标准库提供了URI类,使得处理URI变得更加容易。当然,使用URI类的第一步是获取一个URI实例。假设我们有一个网络资源的地址字符串,有两种方式来获取URI实例:

  • 直接通过地址字符串调用构造函数 - URI myUri = new URI(theAddress);
  • 调用URI.create()静态方法 - URI myUri = URI.create(theAddress);

在本快速教程中,我们将详细探讨这两种方法并讨论它们的区别。

2. 使用URI构造函数

首先,让我们看看构造函数的签名:

public URI(String str) throws URISyntaxException

我们可以看到,如果使用无效的地址调用构造函数,可能会抛出URISyntaxException。为了简化,让我们创建一个单元测试来看这种情况:

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

需要注意的是,URISyntaxExceptionException的子类:

public class URISyntaxException extends Exception { ... }

因此,它是一个检查异常。换句话说,当我们调用这个构造函数时,必须处理URISyntaxException

try {
    URI myUri = new URI("https://www.baeldung.com/articles");
    assertNotNull(myUri);
} catch (URISyntaxException e) {
    fail();
}

我们已经看到了构造函数的使用和作为单元测试的异常处理。如果执行测试,它会通过。但是,如果不使用try-catch代码块,代码将无法编译。

如你所见,使用构造函数创建URI实例相当直接。接下来,我们转向URI.create()方法。

3. 使用URI.create()方法

我们提到URI.create()方法也可以创建URI实例。为了理解create()方法与构造函数之间的差异,让我们看看create()方法的源代码:

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

如代码所示,create()方法的实现很简单。首先,它直接调用构造函数。此外,如果抛出URISyntaxException,它会将异常包装在一个新的IllegalArgumentException中。

现在,让我们创建一个测试,看看如果我们给create()一个无效的URI字符串,是否可以得到预期的IllegalArgumentException

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

如果运行测试,它会通过。

如果我们仔细查看IllegalArgumentException类,我们可以看到它是RuntimeException的子类:

public class IllegalArgumentException extends RuntimeException { ... }

我们知道RuntimeException是不受检查的异常。这意味着当我们使用create()方法创建URI实例时,不需要在显式try-catch块中处理异常

URI myUri = URI.create("https://www.baeldung.com/articles");
assertNotNull(myUri);

因此,create()方法与URI()构造函数的主要区别在于create()方法将构造函数的检查异常(URISyntaxException)转换为不受检查异常(IllegalArgumentException)。

如果我们不想处理检查异常,可以使用create()静态方法来创建URI实例

4. 总结

在这篇文章中,我们讨论了使用构造函数和URI.create()方法创建URI对象的区别。

如往常一样,这里展示的所有代码片段可以在GitHub上找到