Java 17+如何可靠查询Windows系统的Region设置?
Windows系统下Java 17+获取系统Region设置的解决方案
针对你遇到的Locale.getDefault()无法正确返回Windows系统Region设置的问题,以下是两种可行的实现方式:
方法一:通过JNA调用Windows原生API
Windows提供了GetUserDefaultLocaleName API,可直接获取当前用户的区域设置,我们可以用JNA库来调用它:
- 添加JNA依赖(以Maven为例):
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
- 编写调用代码:
import com.sun.jna.Native; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinDef; import java.util.Locale; public class WindowsRegionHelper { public static Locale getSystemRegionLocale() { char[] localeName = new char[128]; WinDef.DWORDByReference length = new WinDef.DWORDByReference(new WinDef.DWORD(localeName.length)); Kernel32.INSTANCE.GetUserDefaultLocaleName(localeName, length); String localeStr = Native.toString(localeName); // 将Windows的区域字符串转换为Java Locale(如"de-CH"转为de_CH) return Locale.forLanguageTag(localeStr.replace('_', '-')); } public static void main(String[] args) { Locale regionLocale = getSystemRegionLocale(); System.out.println("系统Region设置对应的Locale:" + regionLocale); } }
这个方法直接调用系统API,结果准确可靠,能返回对应Region设置的Locale(比如你设置的de_CH)。
方法二:读取Windows注册表
Windows的Region设置存储在注册表HKEY_CURRENT_USER\Control Panel\International路径下的LocaleName键值中,我们可以通过Java读取该值:
import java.util.Locale; import java.util.prefs.Preferences; public class RegistryRegionReader { public static Locale getSystemRegionLocale() { try { Preferences prefs = Preferences.userRoot().node("Control Panel\\International"); String localeName = prefs.get("LocaleName", "en-US"); return Locale.forLanguageTag(localeName.replace('_', '-')); } catch (Exception e) { e.printStackTrace(); return Locale.getDefault(); } } public static void main(String[] args) { Locale regionLocale = getSystemRegionLocale(); System.out.println("系统Region设置对应的Locale:" + regionLocale); } }
注意:这种方式依赖注册表结构的稳定性,若Windows版本更新改变了注册表路径或键名,可能失效,但目前主流Windows版本(10/11)都适用。
补充说明
Locale.getDefault()在Windows上的行为是设计如此:它默认返回的是系统的显示语言(Display language),而非Region设置中的区域格式。所以当系统显示语言为英文、Region设为瑞士德语时,会返回en_US,这不属于BUG,而是Java对Locale的定义和Windows系统设置的映射差异导致的。
内容的提问来源于stack exchange,提问作者mmo
相关产品推荐
相关产品推荐

