为啥 Java 隐藏他们的 getLocalHostName() 实现?

Posted

技术标签:

【中文标题】为啥 Java 隐藏他们的 getLocalHostName() 实现?【英文标题】:Why does Java hide their getLocalHostName() implementation?为什么 Java 隐藏他们的 getLocalHostName() 实现? 【发布时间】:2017-05-12 01:39:06 【问题描述】:

询问如何找到当前机器的主机名是这里和其他编程论坛中更常见的 Java 问题之一,而常见的答案 - InetAddress.getLocalHost().getHostName() 并不是那么好 (as explained here)。

但显然 Java 已经做了正确的事情 - 正如上面提到的 getLocalHost() 方法所记录的那样:

返回本地主机的地址。这是通过从系统中检索主机的名称,然后将该名称解析为 InetAddress 来实现的。

所以如果要使用上面的代码示例,我们基本上要做的是:

    从系统中检索主机名 将名称解析为 Internet 地址 将名称解析回主机名(可能使用本地/etc/hosts文件)

如果您想要的只是第 1 步,这似乎有点多余且容易出错(如果您不在配置良好的服务器上,第 2 步可能会失败,第 3 步也可能会失败)。

getLocalHost() 在内部所做的是在 java.net.InetAddressImpl 的实现上调用 getLocalHostName(),它根据某些系统参数静态实例化为 IPv4 或 IPv6 实现(它甚至不关心平台支持 - 我假设所有特定于平台的编码都在 InetAddressImpl 的本机实现中处理。

那么为什么我们不能直接使用它呢?好吧,我们“不能”,因为到达 getLocalHostName() 的所有入口点都是“包私有”,这实际上没有保护 - 只需将此实现放在类路径中的某个位置并直接访问:

package java.net;
public class HostNameHelper 
    public static String getLocalHostName() throws UnknownHostException 
        return java.net.InetAddress.impl.getLocalHostName();
    

那么为什么要打扰呢?为什么 Sun/Oracle 没有为 Java 开发人员提供他们迫切需要的东西?

【问题讨论】:

我很确定该变通方法不适用于使用 Java 9 模块系统的程序。 好吧,它实际上在 Java 的早期版本中不起作用(至少早在 7 版)-java.net 是一个“受保护的包”,不允许凡人向它添加类。我主要是用它作为开始讨论的借口,但看起来没有接受者...... "我主要是用它作为开始讨论的借口..." Stack Overflow 明确不是论坛。有Stack Overflow Chat。 【参考方案1】:

它在 java 8 中失败了: 引起:java.lang.SecurityException:禁止的包名:java.net

它在 java 9 中失败了: 引起:java.lang.ClassNotFoundException: java.net.HostNameHelper

【讨论】:

以上是关于为啥 Java 隐藏他们的 getLocalHostName() 实现?的主要内容,如果未能解决你的问题,请参考以下文章

java 网络编程

为啥Java限制隐藏方法的访问修饰符[关闭]

为啥隐藏了诸如 index.html 之类的 URL 的“路径”?

我最近才开始Java 今天下载安装了java jdk 后缀名改成了.java 为啥还是显示的本文文档 隐藏后缀名没问题

java学习笔记之TCP实现的简单聊天

java:在java中为啥静态变量没有this引用?