亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中字符編碼問題的解決方法詳解

 更新時(shí)間:2025年09月15日 08:33:13   作者:網(wǎng)羅開發(fā)  
在日常 Java 開發(fā)中,字符編碼問題是一個(gè)非常常見卻又特別容易踩坑的地方,這篇文章就帶你一步一步看清楚字符編碼的來龍去脈,并結(jié)合可運(yùn)行的代碼,看看如何在 Java 項(xiàng)目里徹底解決編碼不一致的問題

前言

在日常 Java 開發(fā)中,字符編碼問題是一個(gè)非常常見卻又特別容易踩坑的地方。尤其是在不同操作系統(tǒng)之間切換,或者從前端傳到后端、再到數(shù)據(jù)庫,編碼沒統(tǒng)一好,中文就會(huì)出現(xiàn)“亂碼”。很多同學(xué)第一次遇到的時(shí)候,會(huì)被一大堆奇怪的方塊符號(hào)或者問號(hào)整崩潰。

這篇文章就帶你一步一步看清楚字符編碼的來龍去脈,并結(jié)合可運(yùn)行的代碼,看看如何在 Java 項(xiàng)目里徹底解決編碼不一致的問題。

背景:為什么會(huì)出現(xiàn)編碼問題

其實(shí)原因很簡(jiǎn)單:不同系統(tǒng)、不同軟件的默認(rèn)字符編碼不一樣。

  • Windows 上默認(rèn)編碼是 GBK 或 CP936。
  • Linux、Mac 大部分是 UTF-8。
  • 數(shù)據(jù)庫可能是 Latin1、GBK 或 UTF-8。
  • Tomcat、IDEA 默認(rèn)也可能不是 UTF-8。

舉個(gè)例子,如果你的 Java 程序里寫了一行中文字符串 "你好",在 UTF-8 下存儲(chǔ)沒問題,但如果有人用 GBK 來讀取,就會(huì)直接炸掉,變成“亂碼”。

常見場(chǎng)景分析

控制臺(tái)輸出亂碼

在 Windows 的 CMD 下運(yùn)行 Java 程序時(shí),經(jīng)常會(huì)看到控制臺(tái)打印中文是亂碼。這是因?yàn)?Windows 控制臺(tái)默認(rèn)用 GBK 編碼,但你的 Java 程序里可能用的是 UTF-8。

public class EncodingDemo {
    public static void main(String[] args) {
        String msg = "你好,世界";
        System.out.println(msg);
    }
}

在 Linux/Mac 控制臺(tái)上運(yùn)行,大概率沒問題。但在 Windows CMD 里,就會(huì)看到一堆奇怪符號(hào)。

文件讀寫亂碼

當(dāng)你從文件里讀中文內(nèi)容時(shí),如果讀的時(shí)候用的編碼和寫的時(shí)候不一樣,也會(huì)直接出錯(cuò)。

import java.io.*;

public class FileEncodingDemo {
    public static void main(String[] args) throws Exception {
        String text = "中文內(nèi)容測(cè)試";

        // 寫入文件,強(qiáng)制使用 UTF-8
        try (Writer writer = new OutputStreamWriter(new FileOutputStream("test.txt"), "UTF-8")) {
            writer.write(text);
        }

        // 讀取文件(錯(cuò)誤示范:不指定編碼)
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            System.out.println("讀到的內(nèi)容:" + reader.readLine());
        }

        // 正確方式:指定 UTF-8
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt"), "UTF-8"))) {
            System.out.println("正確讀到的內(nèi)容:" + reader.readLine());
        }
    }
}

運(yùn)行后你會(huì)發(fā)現(xiàn),沒指定編碼時(shí)中文是亂碼,指定了 UTF-8 之后就正常了。

數(shù)據(jù)庫存取亂碼

數(shù)據(jù)庫也是高頻出錯(cuò)點(diǎn),比如 MySQL 默認(rèn)的 latin1 編碼就很坑。假設(shè)表結(jié)構(gòu)是這樣的:

CREATE TABLE user (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50)
) DEFAULT CHARSET=latin1;

如果你在 Java 里用 UTF-8 往里面寫入 "張三",再讀出來時(shí)就會(huì)發(fā)現(xiàn)已經(jīng)是亂碼。

解決辦法是:

建庫建表時(shí)就指定 utf8mb4

CREATE DATABASE demo DEFAULT CHARSET=utf8mb4;

JDBC 連接時(shí)也要加上編碼參數(shù):

spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC

解決方案

那我們?cè)撛趺唇y(tǒng)一解決這個(gè)問題呢?其實(shí)有幾個(gè)常見思路:

統(tǒng)一使用 UTF-8

UTF-8 是現(xiàn)在最通用的編碼方式,跨系統(tǒng)兼容性最好。所以最穩(wěn)妥的做法就是:整個(gè)鏈路都統(tǒng)一成 UTF-8。
包括:源代碼文件、編譯參數(shù)、運(yùn)行參數(shù)、數(shù)據(jù)庫配置、Tomcat 配置。

比如在 Maven 項(xiàng)目里,你可以在 pom.xml 里強(qiáng)制指定源碼編碼:

<project>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
</project>

這樣即便在 Windows 上編譯,結(jié)果也不會(huì)變。

設(shè)置 JVM 參數(shù)

如果你發(fā)現(xiàn)運(yùn)行環(huán)境默認(rèn)編碼不是 UTF-8,可以在 JVM 啟動(dòng)時(shí)加上參數(shù):

java -Dfile.encoding=UTF-8 -jar app.jar

這會(huì)讓整個(gè) Java 虛擬機(jī)的默認(rèn)編碼改成 UTF-8,很多情況下能一勞永逸。

數(shù)據(jù)庫設(shè)置字符集

在 MySQL 里,推薦直接用 utf8mb4,這樣連 emoji 表情都能存:

ALTER DATABASE demo CHARACTER SET utf8mb4;
ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4;

同時(shí),Java 里的 JDBC 連接也要顯式指定編碼,否則還是會(huì)出問題。

實(shí)際案例:亂碼排查經(jīng)驗(yàn)

我自己就踩過一個(gè)坑:在 Windows 下本地開發(fā),數(shù)據(jù)庫是 utf8mb4,項(xiàng)目里也設(shè)了 -Dfile.encoding=UTF-8,一切正常。但是代碼上線到 Linux 服務(wù)器后,日志里的中文全是亂碼。排查了半天,最后發(fā)現(xiàn)是 日志框架的配置文件沒聲明 UTF-8,導(dǎo)致寫日志文件時(shí)被當(dāng)成系統(tǒng)默認(rèn)編碼。

后來改了一行配置就好了:

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <charset>UTF-8</charset>
    <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>

所以要點(diǎn)就是:不要依賴默認(rèn)值,凡是涉及到字符集的地方都要顯式聲明 UTF-8

總結(jié)

Java 的字符編碼問題,說白了就是“讀和寫不一致”。解決它的核心就是統(tǒng)一,特別是統(tǒng)一用 UTF-8。

  • 源代碼、編譯、運(yùn)行 JVM 都統(tǒng)一 UTF-8。
  • 文件讀寫時(shí)顯式指定編碼。
  • 數(shù)據(jù)庫用 utf8mb4 并在 JDBC 連接里加上參數(shù)。

只要做到這幾點(diǎn),基本就不會(huì)再遇到莫名其妙的亂碼問題。

到此這篇關(guān)于Java中字符編碼問題的解決方法詳解的文章就介紹到這了,更多相關(guān)Java字符編碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java集成kafka實(shí)例代碼

    java集成kafka實(shí)例代碼

    文章介紹了如何在Java項(xiàng)目中集成Apache Kafka以實(shí)現(xiàn)消息的生產(chǎn)和消費(fèi),通過添加Maven依賴、配置生產(chǎn)者和消費(fèi)者、使用SpringBoot簡(jiǎn)化集成以及控制消費(fèi)者的啟動(dòng)和停止,可以實(shí)現(xiàn)高效的消息處理
    2024-12-12
  • TransmittableThreadLocal通過javaAgent實(shí)現(xiàn)線程傳遞并支持ForkJoin

    TransmittableThreadLocal通過javaAgent實(shí)現(xiàn)線程傳遞并支持ForkJoin

    這篇文章主要介紹了TransmittableThreadLocal通過javaAgent實(shí)現(xiàn)線程傳遞并支持ForkJoin詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Java中hutool?List集合對(duì)象拷貝案例代碼

    Java中hutool?List集合對(duì)象拷貝案例代碼

    這篇文章主要給大家介紹了關(guān)于Java中hutool?List集合對(duì)象拷貝的相關(guān)資料,介紹了如何將兩個(gè)不同對(duì)象(Point和CustomData)的特定字段拷貝到一個(gè)中間對(duì)象(IotDataCache)中,并討論了一些在實(shí)現(xiàn)過程中遇到的問題和解決方法,需要的朋友可以參考下
    2024-11-11
  • Java小項(xiàng)目之迷宮游戲的實(shí)現(xiàn)方法

    Java小項(xiàng)目之迷宮游戲的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Java小項(xiàng)目之迷宮的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java并發(fā)編程中的阻塞隊(duì)列解析

    Java并發(fā)編程中的阻塞隊(duì)列解析

    這篇文章主要介紹了Java并發(fā)編程中的阻塞隊(duì)列解析,阻塞隊(duì)列BlockingQueue是一個(gè)支持兩個(gè)附加操作的隊(duì)列,這兩個(gè)附加的操作是在隊(duì)列為空時(shí),獲取元素的線程會(huì)等待隊(duì)列變?yōu)榉强?當(dāng)隊(duì)列滿時(shí),存儲(chǔ)元素的線程會(huì)等待隊(duì)列可用,需要的朋友可以參考下
    2023-08-08
  • RxJava的消息發(fā)送和線程切換實(shí)現(xiàn)原理

    RxJava的消息發(fā)送和線程切換實(shí)現(xiàn)原理

    這篇文章主要介紹了RxJava的消息發(fā)送和線程切換實(shí)現(xiàn)原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11
  • Java編程獲取當(dāng)前屏幕分辨率的方法示例

    Java編程獲取當(dāng)前屏幕分辨率的方法示例

    這篇文章主要介紹了Java編程獲取當(dāng)前屏幕分辨率的方法,涉及java針對(duì)系統(tǒng)硬件信息的相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • 使用idea和gradle編譯spring5源碼的方法步驟

    使用idea和gradle編譯spring5源碼的方法步驟

    這篇文章主要介紹了詳解使用idea和gradle編譯spring5源碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java JVM虛擬機(jī)運(yùn)行機(jī)制

    Java JVM虛擬機(jī)運(yùn)行機(jī)制

    JVM(Java虛擬機(jī))一種用于計(jì)算設(shè)備的規(guī)范,可用不同的方式(軟件或硬件)加以實(shí)現(xiàn)。接下來通過本文給大家簡(jiǎn)單介紹Java JVM虛擬機(jī)運(yùn)行機(jī)制,感興趣的朋友一起看看吧
    2017-03-03
  • 在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程

    在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程

    這篇文章主要介紹了在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程,需要的朋友可以參考下
    2020-07-07

最新評(píng)論