V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Newyorkcity
V2EX  ›  Java

请教一下 Java 里的字符串编码问题。。。老生常谈了

  •  
  •   Newyorkcity · 2020-01-13 14:55:33 +08:00 · 2803 次点击
    这是一个创建于 1777 天前的主题,其中的信息可能已经有所发展或是发生改变。
    假设有一个 java 项目,它的所有文件都按 GBK 编码保存。

    有这样一行代码

    String s = "中文";

    那么当程序运行起来后,JVM 中,s 的编码是什么样的?(对网上说的环境默认的编码不太理解,这里的环境是指什么? JVM ? windows10 ?)

    然后如果我们在这个项目里加一些最简单的 socket 相关的代码,比如获得 socket 的输出流,将 s 输出。那么在输出流里,s 的编码是什么样的?

    谢谢指点!
    10 条回复    2020-01-13 17:43:26 +08:00
    gy123
        1
    gy123  
       2020-01-13 14:58:15 +08:00   ❤️ 1
    jdk 环境会默认根据系统环境设置编码,并且可以修改,所以编程中使用 charset.default 就是跟随系统,或者指定特定编码方式;说错请指正
    lhx2008
        2
    lhx2008  
       2020-01-13 14:59:29 +08:00   ❤️ 1
    JVM 里面都是 char 数组,UTF-16 的,和 GBK UTF-8 无关
    lhx2008
        3
    lhx2008  
       2020-01-13 15:00:42 +08:00
    转流的话,看 API 吧
    Newyorkcity
        4
    Newyorkcity  
    OP
       2020-01-13 15:08:46 +08:00
    @gy123
    @lhx2008
    额。。我怎么感觉你们两说的有冲突。。。。charset.default 一般就是 utf-16 ?
    另外 java 代码所在的文件用什么编码格式保存与实际运行时 JVM 中的字符串编码完全没关系么?


    @lhx2008
    转流的话看 API 能具体说说么,就比如我就很单纯地调用 write 方法,不传任何编码格式的要求的参数,会如何呢?

    谢谢
    Newyorkcity
        5
    Newyorkcity  
    OP
       2020-01-13 15:17:44 +08:00
    再补充一个问题

    就上述假设的项目,里面所有文件都是用 GBK 编码保存的嘛,那假设操作系统的默认编码(这个就是网上说的默认编码?)是 UTF8,那么 String s = "中文“,程序运行起来后,能够正确的理解 s 要被赋的值么?
    lhx2008
        6
    lhx2008  
       2020-01-13 15:18:57 +08:00   ❤️ 1
    @Newyorkcity #4 charset.default 一般是 UTF-8 或者 GBK,socket 的是字节流,你如果用 new PrintWriter 转换 string 到字节流,这里需要 decode,如果你不指定参数,编码用 charset.default
    lhx2008
        7
    lhx2008  
       2020-01-13 15:22:25 +08:00
    @Newyorkcity #5 java 命令有参数 -Dfile.encoding=GBK,如果 java 命令不认识你文件的编码,中文会乱码。至于会不会自动识别,我没试过
    lhx2008
        8
    lhx2008  
       2020-01-13 15:23:37 +08:00
    @lhx2008 #6 decode -> encode 打错了
    guyeu
        9
    guyeu  
       2020-01-13 15:52:36 +08:00
    源代码的编码和运行期的内存毫无关系。
    maokabc
        10
    maokabc  
       2020-01-13 17:43:26 +08:00 via Android   ❤️ 1
    编译后在 class 文件常量池中是 modified utf-8,运行时 String、char 是 utf16,代理对需要使用 2 个 char 表示一个码点。写入流一般包装 DataOutputStream 用 wirteUTF 方法,读取用 DataInputStream 的 readUTF,格式和 class 文件里 utf8 常量一样。源文件编码只能影响到 javac
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3638 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:45 · PVG 12:45 · LAX 20:45 · JFK 23:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.