以下是 Java 中 URL
和 URI
的对比分析,结合代码示例说明差异:
1. 核心定义差异
特性 | URL (Uniform Resource Locator) | URI (Uniform Resource Identifier) |
---|
定义 | 定位资源的位置(必须包含协议和路径) | 标识资源的名称或位置(可包含或不包含位置信息) |
范围 | 是 URI 的子集(必须符合 URI 语法) | 范围更广,包括 URL 和 URN(资源名) |
协议要求 | 必须包含协议(如 http:// , ftp:// ) | 可以是相对路径或无协议的标识符(如 relative/path ) |
2. 功能对比
URL 类
- 用途:专门用于网络资源定位和访问。
- 方法:
openConnection()
:打开网络连接。getProtocol()
, getHost()
, getPort()
:获取协议、主机、端口等信息。- 支持完整的网络操作(如下载文件、发送请求)。
URI 类
- 用途:解析和操作资源标识符的结构。
- 方法:
getPath()
, getQuery()
, getFragment()
:解析路径、查询参数、片段。normalize()
:规范化 URI(处理 ../
或 ./
)。resolve(String reference)
:解析相对路径。
3. 代码示例对比
示例1:URI 可解析相对路径
URI uri1 = new URI("relative/path");
URI uri2 = new URI("http://example.com/path?query=1");
URL url = new URL("http://example.com");
URL invalidUrl = new URL("relative/path");
示例2:URL 的网络操作
URL url = new URL("http://example.com/file.txt");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
示例3:URI 的路径解析
URI uri = new URI("http://example.com:8080/path?query=1#fragment");
System.out.println("Scheme: " + uri.getScheme());
System.out.println("Host: " + uri.getHost());
System.out.println("Port: " + uri.getPort());
System.out.println("Path: " + uri.getPath());
System.out.println("Query: " + uri.getQuery());
System.out.println("Fragment: " + uri.getFragment());
4. 异常处理对比
类 | 构造方法异常 | 典型错误场景 |
---|
URL | MalformedURLException | 格式不合法(如缺少协议或非法字符) |
URI | IllegalArgumentException | 格式不合法(如无效的 URI 结构) |
5. 性能差异
- URI:解析更快,因为仅需验证语法。
- URL:创建时需更多验证(如协议检查、网络可达性预检),开销更大。
6. 使用场景建议
场景 | 推荐使用 | 原因 |
---|
网络资源访问(如 HTTP 请求) | URL | 提供直接的网络操作方法(如 openConnection() ) |
路径解析或规范化 | URI | 支持相对路径和结构化解析 |
安全敏感场景 | URI(避免 URL 的异常风险) | URL 的 MalformedURLException 可能暴露敏感信息 |
总结
- URL:专为网络定位设计,适合直接操作资源。
- URI:通用资源标识符,适合解析、存储和操作资源路径。
- 转换关系:可通过
URI.toURL()
将 URI 转换为 URL(需确保 URI 是有效的 URL 格式)。