【问题标题】:System.getenv() - Behavior depends on whether debug mode is enabledSystem.getenv() - 行为取决于是否启用了调试模式
【发布时间】:2018-01-22 14:14:52
【问题描述】:

我尝试检索我的操作系统的 windows 目录。 为了获得正确的路径,我尝试了以下 2 个命令:

System.getenv().get("WINDIR")
System.getenv().get("SystemRoot")

两个命令都有效,但奇怪的是,第一个命令 (WINDIR) 只返回路径,如果我 在调试模式下运行程序。仅当我在调试模式下运行程序 not 时,后一个命令 (SystemRoot) 才会返回路径。

所以这个程序

public static void main(String[] args) {
    System.out.println(System.getenv().get("WINDIR"));
    System.out.println(System.getenv().get("SystemRoot"));
}

评估为

// Debug mode
C:\Windows
null

// No Debug mode
null
C:\Windows

这是一种已定义的行为吗?

(我的应用程序是特定于 Windows 的,如果我说的是调试模式,我指的是默认的 Eclipse“调试为 Java 应用程序”运行配置)

【问题讨论】:

标签: java eclipse


【解决方案1】:

System.getEnv() 是一种重载方法,一个实现没有参数,一个实现有一个字符串参数。

  • static Map getenv​() 返回当前系统环境的不可修改的字符串映射视图。
  • static String getenv​(String name) 获取指定环境变量的值。

您正在调用不带参数的实现,然后在返回的 Map 上调用 get()From the Javadoc for System.getEnv():

  • 对于 getEnv()返回的地图通常在所有平台上都区分大小写
  • 对于 getEnv(String):在 UNIX 系统上,名称的字母大小写通常很重要,而 在 Microsoft Windows 系统上通常不重要

因此,您的代码必须以正确的大小写提供环境变量的名称,并以全部小写而不是大写指定 windir

也就是说,我根本无法解释您在调试模式下运行时看到的差异。如果我运行下面的程序 - 这只是你的增强版本 - 无论它是否在调试模式下运行,我都会得到相同的结果(如预期的那样):

System.getenv().get() windir=C:\WINDOWS
System.getenv().get() WINDIR=null
System.getenv().get() systemroot=null
System.getenv().get() SystemRoot=C:\WINDOWS
System.getenv()       windir=C:\WINDOWS
System.getenv()       WINDIR=C:\WINDOWS
System.getenv()       systemroot=C:\WINDOWS
System.getenv()       SystemRoot=C:\WINDOWS

您能否将下面的代码运行两次,一次在调试模式下,一次在正常模式下,并告知结果?另外,请告知您的环境:Windows 版本、Eclipse 版本和 Java 版本。

[这更像是要求提供更多信息而不是最终答案,但我无法将其全部放入评论中。]

import java.lang.management.ManagementFactory;
import java.util.regex.Pattern;

public class App {

    private final static Pattern debugPattern = Pattern.compile("-Xdebug|jdwp");

    public static boolean isDebugging() {
        // https://stackoverflow.com/questions/7397584/how-to-know-my-code-is-running-in-debug-mode-in-ide
        // Taken from the code provided by SO user AlexR
        for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
            if (debugPattern.matcher(arg).find()) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {

        System.out.println("Running in debug mode? " + App.isDebugging());
        System.out.println("System.getenv().get() windir=" + System.getenv().get("windir"));
        System.out.println("System.getenv().get() WINDIR=" + System.getenv().get("WINDIR"));
        System.out.println("System.getenv().get() systemroot=" + System.getenv().get("systemroot"));
        System.out.println("System.getenv().get() SystemRoot=" + System.getenv().get("SystemRoot"));
        System.out.println("System.getenv()       windir=" + System.getenv("windir"));
        System.out.println("System.getenv()       WINDIR=" + System.getenv("WINDIR"));
        System.out.println("System.getenv()       systemroot=" + System.getenv("systemroot"));
        System.out.println("System.getenv()       SystemRoot=" + System.getenv("SystemRoot"));
    }

}

【讨论】:

  • 感谢您的努力。我已经运行了这个程序,输出都是:更清晰,更混乱。虽然System.getenv("...") 版本在正常模式和调试模式下具有相同的输出,但System.getenv().get("...") 版本现在确实令人困惑。在正常运行模式下,大写的SystemRoot 和小写的windir 返回所需的值。在调试模式下,只有大写的WINDIR 返回正确的值。我会将输出添加到您的答案中。 (我在 Windows 7 64Bit 上运行 Eclipse Version: Mars.2 Release (4.5.2)
  • 你得到相同的输出吗?或者这是特定于平台的行为?
  • @Schlangguru 我已经包含了我在上面的帖子中得到的输出,无论我是否在调试模式下运行 8 次 println() 调用,我都会得到相同的输出。您能否澄清一下您的 8 项测试中哪一项的结果与我的不同?
  • Re“这是一个特定于平台的行为吗?”....也许。我在 Windows 10 上的 Eclipse Oxygen 2 中运行 Java 1.8。
  • 如果我在正常模式下运行(无调试),我会得到与你相同的输出。在调试模式下,只有大写的System.getenv().get("WINDIR") 和所有的System.getenv("...") 返回正确的目录。其余返回null
猜你喜欢
  • 2021-10-07
  • 2011-04-16
  • 2016-04-03
  • 1970-01-01
  • 2011-12-03
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多