Java中为什么可以用一个char(两个字节)表示一个中文字符

  比如这断程序:

char word = ‘字‘;
System.out.println("字".getBytes().length);       // 输出为 3

其输出结果为3, 小伙伴们就要问了:“奇怪了,‘字‘这个字符,明明是三个字节,怎么可以用char类型的变量来表示? char类型不是在java中是两个字节么?”

  其实,java中有外码和内码之分,顾名思义,外码就是JVM外部使用的编码,比如你在编辑器中输入的“字”,假设是UTF-8编码,UTF-8是变长编码,一个中文可能是1-3个字节来表示;那么,在JVM中,用的都是Unicode码,这是定长编码,所有字符都统一使用两个字节表示,这就是Java的内码。

  "字".getBytes()   JVM执行这段逻辑,实际是进行了编码转换的,可以看String的源码实现:

public byte[] getBytes() {
    return StringCoding.encode(value, 0, value.length);    // 调用StringCoding.encode()      
}
static byte[] encode(char[] ca, int off, int len) {
        String csn = Charset.defaultCharset().name();      // 这里,Charset.defaultCharset()默认是UTF-8
        try {
            // use charset name encode() variant which provides caching.
            return encode(csn, ca, off, len);
        } catch (UnsupportedEncodingException x) {
            warnUnsupportedCharset(csn);
        }

可以看到,Java把字符串"字"(字符串就是char的数组), 编码为UTF-8 , 转为UTF-8的“字”, 它的长度就变成了3个字节哦。

原文地址:https://www.cnblogs.com/yxlaisj/p/11822819.html

时间: 2024-08-29 22:45:55

Java中为什么可以用一个char(两个字节)表示一个中文字符的相关文章

为什么Java中实现多线程的方式有两种?

在面试的过程中,我们经常问被面试者,为什么Java中实现多线程的方式有两种(一种是直接继承Thread类,一种是实现Runnable接口)?可惜的是,很多面试者都答不出来,甚至从来没有想为什么.,那么真正的原因是什么呢?我们可以用反证法推理一下: 假设Java只提供Thread供大家继承从而实现多线程,考虑下面的一个需求,如果有一个已经继承了某个父类的类,但是这个类又想实现多线程,怎么办?很显然,如果只提供一个可以继承的类,肯定解决不了这个问题.那么,如何解决,毫无疑问,就只能使用接口了.

在 Java 中不使用多余变量交换两个字符串

在 Java 中不使用多余变量交换两个字符串 public class Test { public static void main(String[] args) { String a = "Hello"; String b = "World"; System.out.println("Strings before swap: a = " + a + " and b = " + b); a = a + b; b = a.sub

Java中基本数据类型byte,short,char,int,long,float,double

部分内容转自:java 彻底理解 byte char short int float long double 首先说byte: 这段是摘自jdk中 Byte.java中的源代码: 1 /** 2 * A constant holding the minimum value a <code>byte</code> can 3 * have, -2<sup>7</sup>. 4 */ 5 public static final byte MIN_VALUE =

Java中byte、short、char、int、long运算时自动类型转化问题

-------------------------------------------------------------------------------------------------- ★★自动(隐式.默认)类型转换与强制(显式)类型转换★★ 1) boolean类型不参与转换 2) 默认转换 A:从小到大 B:byte,short,char --? int --? long --? float --? double C:byte,short,char之间不相互转换,直接转成int类

java中判断字符串是否相等有两种方法:

1.用“==”运算符,该运算符表示指向字符串的引用是否相同,比如: String a="abc";String b="abc",那么a==b将返回true.这是因为在java中字符串的值是不可改变的,相同的字符串在内存中只会存一份,所以a和b指向的是同一个对象:再比如:String a=new String("abc");String b=new String("abc");那么a==b将返回false,因为a和b指向不同的对

两个队列实现一个栈 + 两个栈实现一个队列

面试中常出现让你手写两个队列实现一个栈,两个栈实现一个队列的问题,很是头疼!今天就仔细将我分析,思考过的Java代码给大家分享一下:(一)两个队列实现一个栈: 两个队列添加元素,哪个队列为空,由于在输出元素时,要进行相应元素的移动(除去尾部元素),所以要在对应不为空的队列进行元素的添加:在输出数据时,要进行两个队列的变相操作,不为空的队列要依次向为空的队列中添加元素,直到尾元素输出即可! /** * 两个队列实现一个栈 * @auther yangchao * @date 2019/7/18 *

Java中判断某一字符串是否包含数字、字母和中文

在Java中判断某一字符串是否为纯英文.纯数字.英文和数字的组合等时,通常使用正则str.matches匹配,告诉这个字符串是否与给定的正则表达式匹配. 各种字符的unicode编码的范围: 汉字:[0x4e00,0x9fa5](或十进制[19968,40869]) 数字:[0x30,0x39](或十进制[48, 57]) 小写字母:[0x61,0x7a](或十进制[97, 122]) 大写字母:[0x41,0x5a](或十进制[65, 90]) import java.util.regex.M

用FileInputStream读取数据,计算机如何实现将两个字节拼接成中文的?

package itcast_02; import java.util.Arrays; /* * 在计算机中如何识别将连个字节转换为中文的呢? * 在计算机中中文的存储为两个字节 : * 第一个字节 : 一定为负数 * 第二个字节 : 可能为负数 (常见), 也可能为正数 ,没有影响 * * */ public class FileInputStreamDemo2 { public static void main(String[] args) { String s = "abcde"

java中读取配置文件ResourceBundle和Properties两种方式比较

今天在开发的时候,需要把一些信息放到配置文件中,方便后续的修改,注意到用的是ResourceBundle读取配置文件的方式,记得之前也见过使用Properties的方式,就比较好奇这两种方式的区别,网上查了一下和查了一下Java API手册,简单总结记录一下: ResourceBundle和Properties的一个主要区别就是ResourceBundle支持语言国际化,当程序需要特定于语言环境的对象时,它使用 getBundle 方法加载 ResourceBundle 类: Locale lo