# 创建 URL

> 原文： [https://docs.oracle.com/javase/tutorial/networking/urls/creatingUrls.html](https://docs.oracle.com/javase/tutorial/networking/urls/creatingUrls.html)

创建`URL`对象的最简单方法是使用`String`来表示 URL 地址的人类可读形式。这通常是另一个人将用于 URL 的表单。在 Java 程序中，您可以使用包含此文本的`String`来创建`URL`对象：

```
URL myURL = new URL("http://example.com/");

```

上面创建的`URL`对象表示 _ 绝对 URL_ 。绝对 URL 包含到达相关资源所需的所有信息。您还可以从 _ 相对 URL_ 地址创建`URL`对象。

## 创建相对于另一个的 URL

相对 URL 仅包含足以相对于另一个 URL（或在其上下文中）到达资源的信息。

相对 URL 规范通常在 HTML 文件中使用。例如，假设您编写了一个名为`JoesHomePage.html`的 HTML 文件。在此页面中，是指向`JoesHomePage.html`和其他页面`PicturesOfMe.html`和`MyKids.html`的链接，这些页面位于同一台机器上，与`JoesHomePage.html`位于同一目录中。来自`JoesHomePage.html`的`PicturesOfMe.html`和`MyKids.html`链接可以像文件名一样指定，如下所示：

```
<a href="PicturesOfMe.html">Pictures of Me</a>
<a href="MyKids.html">Pictures of My Kids</a>

```

这些 URL 地址是 _ 相对 URL_ 。也就是说，URL 是相对于包含它们的文件指定的 - `JoesHomePage.html`。

在 Java 程序中，您可以从相对 URL 规范创建`URL`对象。例如，假设您在站点`example.com`知道两个 URL：

```
http://example.com/pages/page1.html
http://example.com/pages/page2.html

```

您可以相对于它们的公共基本 URL 为这些页面创建`URL`对象：`http://example.com/pages/`，如下所示：

```
URL myURL = new URL("http://example.com/pages/");
URL page1URL = new URL(myURL, "page1.html");
URL page2URL = new URL(myURL, "page2.html");

```

此代码段使用`URL`构造函数，该构造函数允许您从另一个`URL`对象（基础）和相对 URL 规范创建`URL`对象。这个构造函数的一般形式是：

```
URL(URL baseURL, String relativeURL)

```

第一个参数是`URL`对象，它指定新`URL`的基础。第二个参数是`String`，它指定相对于基础的资源名称的其余部分。如果`baseURL`为 null，则此构造函数将`relativeURL`视为绝对 URL 规范。相反，如果`relativeURL`是绝对 URL 规范，则构造函数忽略`baseURL`。

此构造函数还可用于为文件中的命名锚点（也称为引用）创建`URL`对象。例如，假设`page1.html`文件在文件底部有一个名为`BOTTOM`的命名锚。您可以使用相对 URL 构造函数为它创建`URL`对象，如下所示：

```
URL page1BottomURL = new URL(page1URL,"#BOTTOM");

```

## 其他 URL 构造函数

`URL`类提供了两个用于创建`URL`对象的附加构造函数。当您使用 URL（例如 HTTP URL）时，这些构造函数非常有用，这些 URL 在 URL 的资源名称部分中具有主机名，文件名，端口号和引用组件。当您没有包含完整 URL 规范的 String 时，这两个构造函数很有用，但您确实知道 URL 的各种组件。

例如，假设您设计了一个类似于文件浏览面板的网络浏览面板，允许用户选择协议，主机名，端口号和文件名。您可以从面板的组件构造`URL`。第一个构造函数根据协议，主机名和文件名创建`URL`对象。以下代码段在`example.com`站点的`page1.html`文件中创建`URL`：

```
new URL("http", "example.com", "/pages/page1.html");

```

这相当于

```
new URL("http://example.com/pages/page1.html");

```

第一个参数是协议，第二个是主机名，最后一个是文件的路径名。请注意，文件名在开头包含正斜杠。这表示文件名是从主机的根目录指定的。

最后的`URL`构造函数将端口号添加到前一个构造函数中使用的参数列表中：

```
URL gamelan = new URL("http", "example.com", 80, "pages/page1.html"); 

```

这将为以下 URL 创建`URL`对象：

```
http://example.com:80/pages/page1.html

```

如果使用这些构造函数之一构造`URL`对象，则可以使用`URL`对象的`toString`方法或等效的`toExternalForm`方法获取包含完整 URL 地址的`String`。

## 带有特殊字符的 URL 地址

某些 URL 地址包含特殊字符，例如空格字符。像这样：

```
http://example.com/hello world/

```

要使这些字符合法，需要在将它们传递给 URL 构造函数之前对其进行编码。

```
URL url = new URL("http://example.com/hello%20world");

```

对此示例中的特殊字符进行编码很容易，因为只有一个字符需要编码，但对于具有多个这些字符的 URL 地址，或者如果您不确定在编写代码时需要访问哪些 URL 地址，您可以使用 [`java.net.URI`](https://docs.oracle.com/javase/8/docs/api/java/net/URI.html) 类的多参数构造函数自动为您处理编码。

```
URI uri = new URI("http", "example.com", "/hello world/", "");

```

然后将 URI 转换为 URL。

```
URL url = uri.toURL();

```

## MalformedURLException 的

如果构造函数的参数引用`null`或未知协议，则四个`URL`构造函数中的每一个都抛出`MalformedURLException`。通常，您希望通过在`try` / `catch`对中嵌入 URL 构造函数语句来捕获和处理此异常，如下所示：

```
try {
    URL myURL = new URL(...);
} 
catch (MalformedURLException e) {
    // exception handler code here
    // ...
}

```

有关处理异常的信息，请参见[例外](../../essential/exceptions/index.html)。

* * *

**Note:** 

`URL`是“一次写入”对象。一旦创建了`URL`对象，就无法更改其任何属性（协议，主机名，文件名或端口号）。

* * *