String的getBytes()默认编码问题
我们学习java基础的时候.我们都知道在main方法中String的getBytes()方法如果不指定编码格式,默认是UTF-8的方法进行的编码.我们一直认为默认的编码格式就是UTF-8.直到我们学习了javaWeb.在Servlet中.我们通过getBytes()获取的是按照GBK进行编码的.至此我们就有了疑惑.这个getBytes()方法到底是怎么选择默认编码的.我们带着疑惑,去翻一下String的源代码.
[AppleScript] 纯文本查看 复制代码
1
2
3
|
public byte[] getBytes ( ) { return StringCoding.encode ( value , 0 , value .length ) ; } |
继续跟进StringCoding的encode方法
[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
static byte[] encode ( char[] ca , int off , int len ) { String csn = Charset.defaultCharset ( ) . name ( ) ; try { / / use charset name encode ( ) variant which provides caching. return encode ( csn , ca , off , len ) ; } catch ( UnsupportedEncodingException x ) { warnUnsupportedCharset ( csn ) ; } try { return encode ( "ISO-8859-1" , ca , off , len ) ; } catch ( UnsupportedEncodingException x ) { / / If this code is hit during VM initialization , MessageUtils is / / the only way we will be able to get any kind of error message . MessageUtils.err ( "ISO-8859-1 charset not available: " + x.toString ( ) ) ; / / If we can not find ISO -8859 -1 ( a required encoding ) then things / / are seriously wrong with the installation. System.exit ( 1 ) ; return null; } } |
从以上源码中可以看出是通过
[AppleScript] 纯文本查看 复制代码
1
|
String csn = Charset.defaultCharset ( ) . name ( ) ; |
来获取默认编码方式的.我们继续跟进.查看Charset的defaultCharSet()方法.
[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public static Charset defaultCharset ( ) { if ( defaultCharset = = null ) { synchronized ( Charset. class ) { String csn = AccessController.doPrivileged ( new GetPropertyAction ( "file.encoding" ) ) ; Charset cs = lookup ( csn ) ; if ( cs ! = null ) defaultCharset = cs; else defaultCharset = forName ( "UTF-8" ) ; } } return defaultCharset; } |
从以上源码中我们不难看出,不出异常的情况下.默认编码是由file.encoding决定的.我们分别在main方法和Servlet中去获取file.encoding去测试一下.
[AppleScript] 纯文本查看 复制代码
1
2
3
4
5
6
7
|
public class Demo { public static void main ( String[] args ) { System.out.println ( "file.encoding=" + System.getProperty ( "file.encoding" ) ) ; byte[] bytes = "黑马程序员" .getBytes ( ) ; System.out.println ( Arrays.toString ( bytes ) ) ; } } |
输出结果是
[AppleScript] 纯文本查看 复制代码
1
2
|
file .encoding = UTF -8 [ -23 , -69 , -111 , -23 , -87 , -84 , -25 , -88 , -117 , -27 , -70 , -113 , -27 , -111 , -104 ] |
在Servlet中的测试代码:
[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@WebServlet ( "/user/findAllServlet" ) public class ServletDemo 1 extends HttpServlet { protected void doPost ( HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException { System.out.println ( "findAllServlet..." ) ; System.out.println ( "file.encoding=" + System.getProperty ( "file.encoding" ) ) ; byte[] bytes = "黑马程序员" .getBytes ( ) ; System.out.println ( Arrays.toString ( bytes ) ) ; } protected void doGet ( HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException { this.doPost ( request , response ) ; } } |
输出结果是:
[AppleScript] 纯文本查看 复制代码
1
2
|
file .encoding = GBK [ -70 , -38 , -62 , -19 , -77 , -52 , -48 , -14 , -44 , -79 ] |
getBytes()方法的默认编码确实是跟file.encoding一致的.file.encoding是由谁决定的呢?网上很多流传说是跟当前文件的编码格式相同.那我们测试一下.
在idea中我们讲文件的编码格式改成GBK.
<ignore_js_op>

发现事与愿违.file.encoding依然是UTF-8的.也就是说file.encoding跟文件的编码没有任何关系.相同的代码.我们用命令行窗口去编译和运行.发现file.encoding竟然变成了GBK
[AppleScript] 纯文本查看 复制代码
1
2
3
|
C : \Users\yanjingpan\Desktop > java Demo file .encoding = GBK [ -70 , -38 , -62 , -19 , -77 , -52 , -48 , -14 , -44 , -79 ] |
我们讲Demo.java文件改成UTF-8编码格式的用 javac -encoding utf-8 Demo.java进行编译.然后运行发现file.encoding竟然没有变:
[AppleScript] 纯文本查看 复制代码
1
2
3
|
C : \Users\yanjingpan\Desktop > java Demo file .encoding = GBK [ -70 , -38 , -62 , -19 , -77 , -52 , -48 , -14 , -44 , -79 ] |
这说明file.encoding跟编译环境没有关系.只跟运行环境有关.我们尝试运行的时候指定file.encoding编码:
[AppleScript] 纯文本查看 复制代码
1
|
java - Dfile.encoding = utf -8 Demo |
运行结果就是:
[AppleScript] 纯文本查看 复制代码
1
2
|
file .encoding = utf -8 [ -23 , -69 , -111 , -23 , -87 , -84 , -25 , -88 , -117 , -27 , -70 , -113 , -27 , -111 , -104 ] |
运行时将file.encoding指定成gbk
[AppleScript] 纯文本查看 复制代码
1
|
java - Dfile.encoding = gbk Demo |
运行结果就是:
[AppleScript] 纯文本查看 复制代码
1
2
3
|
C : \Users\yanjingpan\Desktop > java Demo file .encoding = GBK [ -70 , -38 , -62 , -19 , -77 , -52 , -48 , -14 , -44 , -79 ] |
到此我们就知道了.Tomcat在启动的时候将file.encoding指定成了gbk.所以我们在Servlet中获取字节码数组的时候,默认用的就是gbk.
Tomcat是根据当前操作系统来设置file.encoding的值.我电脑是windows简体中问的.所以默认就是GBK的.
我们可以在catalina.bat中将file.encoding设置成utf-8.
[AppleScript] 纯文本查看 复制代码
1
|
set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dfile.encoding=UTF-8" |
重启Tomcat.再访问我们的Servlet.file.encoding就改成UTF-8的了.
<ignore_js_op>
至此,困扰我们的getBytes()默认编码格式问题就解决了.
更多免费技术资料可关注:annalin1203
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架