java 解码_java编码解码过程

本文深入探讨了Java中出现中文乱码问题的原因,包括编码、解码的原理,以及如何通过设置正确的字符集避免乱码。文章通过实例代码展示了如何进行字符串的编码和解码操作,并分析了为何需要在数据库连接URL中指定编码格式。同时,文章提到了常见的字符集如ASCII、ISO-8859-1、GB2312、GBK和UTF-8等,强调了解决乱码问题时需要确保编码和解码过程的一致性。
摘要由CSDN通过智能技术生成

最近做项目的时候,有时会遇到中文乱码的问题,网上查询了很多资料,发现大多都是只讲解决方案,并没有讲到为什么要使用这种方案,这种方案的原理是什么?

最典型的就是连接数据库的URL,我们一般把它放到classpath下的db.properties中,然后尽管我们的java代码设置了UTF-8,JSP也设置了UTF-8,数据库也设置了UTF-8,但是插入数据到数据库中仍然会出现中文乱码,最后我们的解决方案是在连接数据库的URL上加上连接使用的编码格式UTF-8,但是我们会纳闷为什么要这么做呢?

下面我们来聊下java编码的问题,为什么要编码,有哪些编码,怎么编码和解码,为什么会有中文乱码,怎么解决中文乱码。

1.为什么要编码

这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言。由于人类的语言太多,因而表示这些语言的符号太多,无法使用计算机中一个基本的存储单元---byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机理解我们的语言。我们可以把计算机能够理解的语言假定为英语,其他语言要能够在计算机中使用必须经过一次翻译,把它翻译成英语。这个翻译的过程就是 编码。

所以总的来说,编码的原因可以总结为:计算机中存储信息的最小单元是一个字节,即8个bit,所以能表示的字符范围是0-255个;人类要表示的符号太多,无法用一个字节来完全表示。

要解决这个矛盾必须要有一个新的数据结构char,从char到byte必须编码。

2.常见的编码

明白了各种语言需要交流,经过翻译是必须的,那么又如何来翻译呢?计算机中提供了多种翻译方式,常见的右ASCII,ISO-8859-1,GB2312,GBK,UTF-8,UTF-16等。他们可以被看做字典,他们规定了转化的规则,按照这个规则可以让计算机正确地标识我们的字符。目前的编码格式很多,如GB2312,GBK,UTF-8,UTF-16都可以标识一个汉字,那我们到底选择哪种编码格式来存储汉字呢?这就要考虑其他因素呢,是存储空间重要还是编码的效率重要。

3.怎么编码,解码

以String为例,代码如下:

String s="这是一段中文字符串";byte[] b=s.getBytes("UTF-8");

String n=new String(b,"UTF-8");

编码的用途:把我们用户能够认识的语言转化为计算机能够认识的语言,一般用在传输或者存储时,也就是涉及到计算机的操作而不是针对用户而言。

解码:把字节码解释为我们用户能够认识的语言。

4.为什么有中文乱码

第一种情况:使用不能识别中文的字符集来编码,这种情况比较少见

第二种情况,使用一种字符集来编码,却用另一种字符集来解码,这种比较多见,比如,java代码采用UTF-8编码,但是访问数据库的时候,数据库采用GBK来解码,这就会出现中文乱码。

Charset使用

Charset charset=Charset.forName("UTF-8");

ByteBuffer byteBuffer=charset.encode(string);

CharBuffer charBuffer=charset.decode(byteBuffer);

5.java中怎么编解码

String name="I am 小明";

toHex(name.toCharArray());

try{byte[] iso8859=name.getBytes("ISO-8859-1");

toHex(iso8859);byte[] gb2312=name.getBytes("GB2312");

toHex(gb2312);byte[] gbk=name.getBytes("GBK");

toHex(gbk);

}

String str="小米";byte[] b=str.getBytes("UTF-8");

public byte[] getBytes(String charsetName)

throws UnsupportedEncodingException {if (charsetName == null) throw newNullPointerException();return StringCoding.encode(charsetName, value, 0, value.length);

}

static byte[] encode(String charsetName, char[] ca, int off, intlen)

throws UnsupportedEncodingException

{

StringEncoder se=deref(encoder);

String csn= (charsetName == null) ? "ISO-8859-1": charsetName;if ((se == null) || !(csn.equals(se.requestedCharsetName())||csn.equals(se.charsetName()))) {

se= null;try{

Charset cs= lookupCharset(csn); //生成字符集实例

if (cs != null)

se= newStringEncoder(cs, csn);

}catch(IllegalCharsetNameException x) {}if (se == null)throw newUnsupportedEncodingException (csn);set(encoder, se);

}returnse.encode(ca, off, len);

}

private staticCharset lookupCharset(String csn) {if(Charset.isSupported(csn)) {try{returnCharset.forName(csn);

}catch(UnsupportedCharsetException x) {throw newError(x);

}

}return null;

}

privateStringEncoder(Charset cs, String rcn) {this.requestedCharsetName =rcn;this.cs =cs;this.ce =cs.newEncoder()

.onMalformedInput(CodingErrorAction.REPLACE)

.onUnmappableCharacter(CodingErrorAction.REPLACE);this.isTrusted = (cs.getClass().getClassLoader0() == null);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值