推荐
ANSI - 百度百科
字符编码笔记:ASCII,Unicode 和 UTF-8
Java中文乱码解决之道
从外部编码的角度再议 Java 乱码问题
实验一 目的:源文件编码方式、javac编译参数encoding 二者的关系?
先阅读文章 java中文乱码解决之道(四)——java编码转换过程 、 Java源文件到字节码等情况的编码转换
情况
源文件编码
javac读取源文件编码
javac编译结果
一
含中文 UTF-8
GBK
失败
二
含中文 ANSI
GBK
成功
三
含中文 ANSI
UTF-8
失败
四
纯英文 任意
任意
成功
GBK 汉字占两个字节;UTF-8 汉字大多占三个字节,有些占4个字节。
1 2 3 4 javac ANSI.java javac UTF8.java javac -encoding GBK ANSI.java javac -encoding UTF-8 UTF8.java
实验二 目的:找出导致cmd控制台乱码的因素,源文件编码、class文件编码、jvm编码、控制台编码。
无论源文件使用什么编码方式存储,无论内容是中文字符还是英文字符,编译后的class文件内容都是Unicode编码。所以源文件编码和class文件编码不会影响cmd控制台乱码。
1 2 3 4 5 # 改变控制台编码 chcp 65001 # UTF-8 chcp 936 # GBK # 指定jvm编码;若未指定就使用Windows默认的GBK编码。 java -jar -Dfile.encoding=UTF-8 service-sys-start.jar
System.out.println乱码 将下面内容分别另存为 ANSI.java 、UTF8.java ,文件名=类名=文件编码 。
1 2 3 4 5 6 7 8 9 10 11 12 public class ClassName { public static void main (String[] args) { System.out.println("当前JRE版本:" + System.getProperty("java.version" )); System.out.println("当前JVM的默认字符集:" + System.getProperty("file.encoding" )); System.out.println("java后面跟着的是java文件的类名,后面不要加.class。" ); System.out.println("java后面跟着的是java文件的类名,后面不要加.class。" ); System.out.println("java后面跟着的是java文件的类名,后面不要加.class。" ); } }
运行:
1 2 3 4 5 6 7 8 9 10 11 chcp 936 java ANSI # 正常 java UTF8 # 正常 java -Dfile.encoding=UTF-8 ANSI # 正常 java -Dfile.encoding=UTF-8 UTF8 # 正常 chcp 65001 java ANSI # 乱码 java UTF8 # 乱码 java -Dfile.encoding=UTF-8 ANSI # 正常 java -Dfile.encoding=UTF-8 UTF8 # 正常
结论:
控制台编码
jvm编码
是否乱码
GBK
GBK
否
GBK
UTF-8
否
UTF-8
UTF-8
否
UTF-8
GBK
是
log4j2打印控制台乱码 日志配置文件中已经指定了console输出源是UTF-8编码,所以保证控制台是UTF-8即可(chcp 65001)。
启动脚本 1 2 3 4 5 6 7 8 chcp 65001 set JAVA_HOME=D:\Program Files\Java64\jdk1.8.0_192 set PATH=%JAVA_HOME%\bin; set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 :: 开启远程调试 set JAVA_TOOL_OPTIONS=%JAVA_TOOL_OPTIONS% -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 java -jar -Dserver.port=60001 service-sys-start.jar pause;
各种OPTIONS的区别 也许你经常遇到 JAVA_OPTS
、_JAVA_OPTIONS
和 JAVA_TOOL_OPTIONS
,那么他们有什么不同呢?
JAVA_OPTS
:常用于一些应用的配置,如Tomcat,但它一般不作为环境变量,也不能被JVM识别的,是那些应用的自定义配置;
_JAVA_OPTIONS
:也是作为环境变量来替代命令行参数的,但它是 JVM 厂家自定义的,可以覆盖 JAVA_TOOL_OPTIONS
,但各厂家的不同,_JAVA_OPTIONS
是 Oracle 的 JVM,而 IBM 的则是用 IBM_JAVA_OPTIONS
。
JAVA_TOOL_OPTIONS
:是标准的,所有虚拟机都能识别和应用的。
如果想验证上面的不同也不难,如果设置了 JVM 能识别的环境变量,JVM会有”Picked up”的提示的,如:
1 2 3 4 5 6 7 8 9 10 11 :: 能被JVM识别 set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 java -version :: 能被JVM识别 set _JAVA_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 java -version :: 不能被JVM识别 set JAVA_OPTS=-Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 java -version
可见 _JAVA_OPTIONS
覆盖了 JAVA_TOOL_OPTIONS
JAVA_TOOL_OPTIONS
用于解决的经典问题是使用命令行导致中文乱码