如何确定 Java 在 Windows 上是 运行
How to determine that Java is running on Windows
我想确定 Java 是否是 Windows 上的 运行,并且看到了许多不同的建议,其中包括系统的各种排列 属性 os.name
与 startsWith
/ indexOf
/ contains
/ toLowerCase(Locale.ENGLISH)
/ toLowerCase()
,或只是 File.separatorChar
.
我扫描了 JDK 源代码以查看是否有明确的答案(见下文)和其他一些建议的 SO 帖子:
String os = System.getProperty("os.name" /**, "<Surely os.name is never null?>" */);
List<Boolean> isWindows = List.of(
os.startsWith("Windows"),
os.contains("Windows"),
os.toLowerCase().startsWith("windows"),
os.toLowerCase().contains("windows"),
os.toLowerCase(Locale.ENGLISH).contains("windows"),
os.toLowerCase(Locale.ENGLISH).startsWith("windows"),
File.separatorChar == '\'
);
System.out.println("os.name ="+os);
System.out.println("os.name(UTF-8)="+Arrays.toString(os.getBytes(StandardCharsets.UTF_8)));
System.out.println("isWindows ="+isWindows);
是否存在 OS/语言安装的任何排列错误地使用上述条件识别 isWindows
,其中 true/false 不一致或错误?
// For Windows I would expect all true, such as:
os.name =Windows 10
os.name(UTF-8)=[87, 105, 110, 100, 111, 119, 115, 32, 49, 48]
isWindows =[true, true, true, true, true, true, true]
// For non-Windows I would expect all false such as:
os.name =Linux
os.name(UTF-8)=[76, 105, 110, 117, 120]
isWindows =[false, false, false, false, false, false, false]
JDK 源代码示例
供参考,这是在 Open JDK17 源代码中检测到 isWindows
的地方(来自最近的 git fetch
非最终候选版本):
src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java
System.getProperty("os.name").toLowerCase().startsWith("win"));
src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
isWindows = System.getProperty("os.name").startsWith("Windows"))
src/java.desktop/share/classes/sun/font/FontUtilities.java
isWindows = System.getProperty("os.name", "unknownOS").startsWith("Windows");
src/java.base/share/classes/java/util/zip/ZipFile.java
src/java.desktop/share/classes/sun/awt/OSInfo.java
VM.getSavedProperty("os.name").contains("Windows")
System.getProperty("os.name").contains("Windows")
src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java
boolean isWindows = osName != null && osName.contains("Windows");
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java
boolean isWin32 = (File.separatorChar == '\')
src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java
Note that I've omitted this test in case of confusion with Darwin OS:
String os = System.getProperty("os.name").toLowerCase();
if (os.indexOf("win") >= 0) {
platform = Platform.WINDOWS;
}
在注意到各种评论和其他帖子后,我没有找到不继续使用我当前代码中的 isWindows
检查的理由,这只是列出的第一个测试:
boolean isWindows = System.getProperty("os.name").startsWith("Windows");
我问题中的前六项测试似乎正确检测了 isWindows
,但没有正确检测到最后一项 File.separatorChar == '\'
(因为 OS/2 也是如此)。
请注意,在土耳其语中,“I”的小写值不等于“i”。尝试:
"I".toLowerCase(Locale.forLanguageTag("TR")).equals("i") // char:305
"i".toUpperCase(Locale.forLanguageTag("TR")).equals("I") // char:304
也许这解释了为什么一些开发人员使用 .toLowerCase(Locale.ENGLISH)
但任何测试结果都没有改变,除非 os.name
属性 在土耳其语安装中是大写的。
感谢所有建议。
我想确定 Java 是否是 Windows 上的 运行,并且看到了许多不同的建议,其中包括系统的各种排列 属性 os.name
与 startsWith
/ indexOf
/ contains
/ toLowerCase(Locale.ENGLISH)
/ toLowerCase()
,或只是 File.separatorChar
.
我扫描了 JDK 源代码以查看是否有明确的答案(见下文)和其他一些建议的 SO 帖子:
String os = System.getProperty("os.name" /**, "<Surely os.name is never null?>" */);
List<Boolean> isWindows = List.of(
os.startsWith("Windows"),
os.contains("Windows"),
os.toLowerCase().startsWith("windows"),
os.toLowerCase().contains("windows"),
os.toLowerCase(Locale.ENGLISH).contains("windows"),
os.toLowerCase(Locale.ENGLISH).startsWith("windows"),
File.separatorChar == '\'
);
System.out.println("os.name ="+os);
System.out.println("os.name(UTF-8)="+Arrays.toString(os.getBytes(StandardCharsets.UTF_8)));
System.out.println("isWindows ="+isWindows);
是否存在 OS/语言安装的任何排列错误地使用上述条件识别 isWindows
,其中 true/false 不一致或错误?
// For Windows I would expect all true, such as:
os.name =Windows 10
os.name(UTF-8)=[87, 105, 110, 100, 111, 119, 115, 32, 49, 48]
isWindows =[true, true, true, true, true, true, true]
// For non-Windows I would expect all false such as:
os.name =Linux
os.name(UTF-8)=[76, 105, 110, 117, 120]
isWindows =[false, false, false, false, false, false, false]
JDK 源代码示例
供参考,这是在 Open JDK17 源代码中检测到 isWindows
的地方(来自最近的 git fetch
非最终候选版本):
src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java
System.getProperty("os.name").toLowerCase().startsWith("win"));
src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java
src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
isWindows = System.getProperty("os.name").startsWith("Windows"))
src/java.desktop/share/classes/sun/font/FontUtilities.java
isWindows = System.getProperty("os.name", "unknownOS").startsWith("Windows");
src/java.base/share/classes/java/util/zip/ZipFile.java
src/java.desktop/share/classes/sun/awt/OSInfo.java
VM.getSavedProperty("os.name").contains("Windows")
System.getProperty("os.name").contains("Windows")
src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java
boolean isWindows = osName != null && osName.contains("Windows");
src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java
boolean isWin32 = (File.separatorChar == '\')
src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java
Note that I've omitted this test in case of confusion with Darwin OS:
String os = System.getProperty("os.name").toLowerCase();
if (os.indexOf("win") >= 0) {
platform = Platform.WINDOWS;
}
在注意到各种评论和其他帖子后,我没有找到不继续使用我当前代码中的 isWindows
检查的理由,这只是列出的第一个测试:
boolean isWindows = System.getProperty("os.name").startsWith("Windows");
我问题中的前六项测试似乎正确检测了 isWindows
,但没有正确检测到最后一项 File.separatorChar == '\'
(因为 OS/2 也是如此)。
请注意,在土耳其语中,“I”的小写值不等于“i”。尝试:
"I".toLowerCase(Locale.forLanguageTag("TR")).equals("i") // char:305
"i".toUpperCase(Locale.forLanguageTag("TR")).equals("I") // char:304
也许这解释了为什么一些开发人员使用 .toLowerCase(Locale.ENGLISH)
但任何测试结果都没有改变,除非 os.name
属性 在土耳其语安装中是大写的。
感谢所有建议。