(背景部分只是个引子,并不很重要,不感兴趣的话可以直接跳过,从思考部分开始看起)
最近因公司项目需要,使用javaFx开发了一个桌面客户端。因为客户群都是windows桌面,所以我采用了maven的javapackager插件将其打包成exe安装文件。
然后,就遇到了中文乱码问题,下意识的百度了一下,看到几种方法,总结下来有以下几种:
java -jar app.jar -Dfile.encoding=UTF-8
<properties>
<maven.compiler.encoding>UTF-8maven.compiler.encoding>
properties>
结果是,每种我都试了,但我运气没别人好,没成功啊!!!
然后我静下心来想了想,还是我自己懒惰了,不愿意动脑子,想走捷径,这显然是不对的。
于是乎,我开始仔细思考问题到底出在哪?
乱码是怎么产生的呢?这个对于我来说没有太多的障碍,因为我在刚入行时候花了很长一段时间研究它,最后弄明白了。这里不讲很多理论的东西,就打个比方。
比如:小明是一个中国人,从小精通汉语拼音的读写。有一天小明收到了一份来自外国友人的微信漂流瓶,上面写着:hello world。然后小明开始利用学过的汉语拼音翻译这句话:和llo 我rld。小明瞬间就懵了,乱码了,看不懂啊!!!
在我们平时的开发中,一个java文件就是一封信,这封信的内容通常被一个叫UTF-8的方法编码成一串0101010存储在磁盘上。而我们知道,java文件要被编译成class文件才能被JVM执行。这里就需要有一段程序他要认识UTF-8生成的010101,然后再把它编译成class文件,同样的class文件也会用UTF-8编码成01010101存储在磁盘上。最后就是运行,JVM读取class文件,然后开始运行,这时候就要求JVM也能读懂UTF-8写的class文件,这样才能正确的运行。
我有一个如下的java文件:
public class LuanMa{
public static void main(String[] args){
System.out.print("我是中国人");
}
}
step1. 首先我要确保这个java文件是UTF-8编码的,然后这里的"我是中国人"被编码成:6211662F4E2D56FD4EBA存在磁盘上。
step2. 使用javac编码此文件,此时会先读取出此文件的内容,然后使用UTF-8读到了6211662F4E2D56FD4EBA这个字符串,又使用UTF-8编码原封不动的写到了class文件中。
step3. JVM读入刚刚编译的class文件。它也是使用UTF-8的形式读的,读到了6211662F4E2D56FD4EBA,然后通过字符集映射到了我是中国人几个汉字显示在了屏幕上。
!!!划重点:非常显然,只要保证文件本身编码,编译使用的编码,和JVM读取class的编码都是一种编码,字符串就不会乱码。
有了上面的理论基础,按部就班就很容易解决上面遇到的乱码问题了,首先保证文件的编码是UTF-8
IDEA的setting里面如下配置:
然后确认下文件是不是UTF-8编码:
现在大家大多使用maven,所以这里以maven为例说明。
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>{插件版本}version>
<configuration>
<source>{java代码的语法版本}source>
<target>{编译成class文件的版本}target>
<encoding>UTF-8encoding>
configuration>
plugin>
也有说下面这样直接配就生效的,但是我没生效,大家可以试试,反正目的是一样的。
<properties>
<maven.compiler.encoding>UTF-8maven.compiler.encoding>
properties>
这一步通常不需要,因为是默认的。
java -jar app.jar -Dfile.encoding=UTF-8
大家可以从头一步一步来,不需要三步都做,到哪部成功了,后面就不需要了。
大家会发现,整个过程就是一开头百度出来的三种方法,我们可以猜测,之所以有人只用一种方法就解决了,是因为其他两个条件他是满足的。最后总结一下,盲目百度或许可以解决一时的问题,但是想要提高自己,还是需要深入学习深入思考。