1、Java的运行环境中,String是什么编码?

使用java做程序设计语言,字符编码是和jvm相关的,和操作系统无关。

java默认的编码是jvm在安装的时候就确定了的,它是根据你的系统的环境确定并默认的。

我们可以通过java的Charset类的defaultCharset()方法来获取它默认的字符编码。

我安装的JDK是1.7,系统环境是64位,获取的默认的字符编码是utf16的,并且是Big-Endian(这点我比较奇怪,我的机器是Little-endian的,而虚拟机竟然默认是大端的编码)。

看如下代码:

String name = "张三";

Charset def    = Charset.defaultCharset();             // 获取系统默认的编码   def = utf-16(Big-Endian)
Charset utf8   = Charset.forName("UTF-8");       
Charset gbk   = Charset.forName("GBK");

byte[] bdefult     = name.getBytes();                    //    获取的name的字节流  = [-2, -1, 95, 32, 78, 9]
byte[] butf16Big = name.getBytes(def);               //    name转换为utf16(Big-Endian)后的字节流  =  [-2, -1, 95, 32, 78, 9]
byte[] bgbk       = name.getBytes(gbk);               //    name转换为gbk后的字节流  =  [-43, -59, -56, -3]
byte[] butf8       = name.getBytes(utf8);             //     name转换为utf8后的字节流  =  [-27, -68, -96, -28, -72, -119]

由此我们可以看出执行String name = "张三"后String存储的就已经是系统默认的字符编码了utf16(Big-Endian)。

可能细心的人会发现,为什么"张三"的字节数是[-2, -1, 95, 32, 78, 9]有6个字节呢?不是utf16每个字符是占用两个字节来表示的呀。

对的,往下看:

Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。

(Unicode是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。)

在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。

我们知道单字节的字符的表示(char)是没有大小端之分的,而ushort、int、long、int64等类型才有大小端之分,故gbk和utf8的字节流不需要表示它是否是大小端,而utf-16(即ushort)的字节流是需要告知它是大端or小端。

由于 Java 中的String默认采用带有 UCS2 的 UTF-16BE 拆分的,所以我们需要在字节流前面加上(FE, FF)告知是大端的。

其实 [-2, -1, 95, 32, 78, 9] = [FE, FF, 95, 32, 78, 9],所以前面两个字节的含义只是表明存储的字节流是大端还是小端的,方便传输的时候识别,并无其它的含义。

总结:

(1)、java默认的字符编码是虚拟机决定的,并与系统无关。

(2)、Unicode和UTF-16:1个字符占2个字节(不管是哪国语言)

(3)、Java中的char默认采用Unicode编码,所以Java中一个char也占2个字节

 2、c和c++语言

 大家都知道c和c++语言是没有java一样的虚拟机的,它们最终都是调用的系统的API,这就注定了它最终调用的接口是和系统相关的。

(1)、windows系统

VC/VS的C++开发环境,它实现的标准C++接口有不少肯定是需要使用windows api的。

要了解Win32子系统的DLL们提供了哪些API,最直接的方法就是用Win32dsm直接查看DLL们的导出表。这时我们会发现Win32 API中带字符串的API一般都有两个版本,例如CreateFileA()和CreateFileW()。当然也有例外,例如GetProcAddress函数。

A代表ANSI代码页,W是宽字符,即Unicode字符。Windows中的Unicode字符一般指UCS2的UTF16-LE编码。让我们通过几个实例观察A/W版本间的关系。

我们用WIn32dsm查看gdi32.dll的汇编代码,可以看到CreateFileA()调用GdiGetCodePage()获取当前代码页,再调用MultiByteToWideChar()转换输入的字符串,然后调用一个内部函数。而CreateFileW()直接调用这个内部函数。

故可以判断windows系统API内部实现是用UCS2的UTF16-LE编码。故windows api我们尽量使用宽字符的接口。

了解windows的API实现是用UCS2实现的后,那它的单字节的接口怎么转换成UCS2的呢?

windows的API提供setlocale接口可以设置当前程序使用的字符编码信息。故你通过此接口告诉windows你当前程序中char*使用的字符编码是什么。

获取当前程序的字符编码信息:      char* pLocale = setlocale(LC_ALL, NULL);     可以了解到C++默认的字符编码是C locale。

设置当前程序为系统环境字符编码:char* pLocale = setlocale(LC_ALL, "");          如果是简体中文版的话,即等同与setlocale(LC_ALL, ".936")。

(2)、Linux系统

本人对linux系统的API实现了解不深,不过据网上资料说它是用的UTF-8字符编码实现的。

有兴趣的人可以研究libstdc++,它实现了linux上的标准C++接口,可以看它的源码了解了解,其中应该有不少调用linux系统函数的方法。

3、总结:

(1)、Windows的系统API使用UCS2的UTF16-LE编码实现,linux的系统API使用UTF-8编码实现。

(2)、JAVA默认的字符编码与jvm相关,一般默认为UCS2的UTF-16BE编码,与系统无关。

(3)、C/C++的默认字符编码为C locale,用户可以通过setlocale()修改当前程序的字符编码环境。

操作系统和程序设计语言的API使用的字符编码分析的更多相关文章

  1. 【miscellaneous】【C/C++语言】UTF8与GBK字符编码之间的相互转换

    UTF8与GBK字符编码之间的相互转换 C++ UTF8编码转换 CChineseCode 一 预备知识 1,字符:字符是抽象的最小文本单位.它没有固定的形状(可能是一个字形),而且没有值." ...

  2. 《c程序设计语言》读书笔记--统计字符数

    #include <stdio.h> #define MAXLINE 1000 int getline(char line[],int maxline); void copy(char t ...

  3. python语言简介、解释器、字符编码介绍

    一.为什么要选择python作为学习语言: 各个语言的对比: C和python.java.C#等 C语言:代码编译得到机器码,机器码在处理器上直接执行,每一条指令控制cpu工作 其他语言:代码编译得到 ...

  4. Notes 20180506 : Java程序设计语言概述

    2.Java程序设计语言概述 如果对于开发语言的排行榜有所关注的话,那么会发现很长一段时间以来Java都是位居榜首的高级开发语言,作为一个Java开发者,为此感到骄傲的同时也深感忧虑,骄傲的是自己接触 ...

  5. linux 操作系统下c语言编程入门

    2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 6)Linux程序设计入门--消息管理  ...

  6. Oberon程序设计语言简介

    Oberon奥伯龙是一种通用编程语言,也是一种同名操作系统(由Oberon语言开发,且参考过贝尔实验室的新一代网络操作系统Plan9),是由原Pascal程序设计语言的发明者Niklaus Wirth ...

  7. 《C程序设计语言》【PDF】下载链接:

    <C程序设计语言>[PDF]下载 https://u253469.pipipan.com/fs/253469-230382180 内容简介 在计算机发展的历史上,没有哪一种程序设计语言像C ...

  8. 《程序设计语言——实践之路》【PDF】下载

    程序设计语言--实践之路>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382240 内容简介 本书在美国大学已有使用了十余年,目前被欧 ...

  9. [零] JavaIO入门简介 程序设计语言 为什么需要IO库

     本文旨在引申出来Java IO的概念含义,作为学习JavaIO一个起步的了解知识点 部分内容引自<计算机操作系统第三版>  操作系统的文件管理   "在现代计算机系统中,要用到 ...

随机推荐

  1. 搜集资料&安装环境

    开始入坑DSP,芯片是TI的TMS320C6678,硬件平台为TI官方的TMS320C6678L开发板. 官方给的资料有很多,各种用户手册.软件支持包,眼花缭乱.先尝试把开发环境搭起来,跑个Hello ...

  2. ireport5.6+jasperreport6.3开发(三)--以javabean为基准的报表开发(javabean)

    这里只有ireport的开发没有web侧的程序. ireport的数据源可以说是多种多样,大致可以通过文件 数据库 bean类这三种方式,这里只介绍bean类 (数据库比较简单可参考其他的网站,文件没 ...

  3. 关于absolute 和 relative 定位的定义

    absolute的英文意思是绝对的意思,实际上是针对父级元素元素定位,如果父级元素没有position:relative|absolute,则追至再上一个父级元素,直至相对于文档的左上角定位,按照我们 ...

  4. php案列4

    一个最简单的利用php生成随机数或者随机字符串的函数.$chars变量中的字符自己修改就能达到数字或者字符串的目的     $len表示长度,代码如下: 复制代码 代码如下: /** * 产生随机字符 ...

  5. hexo deploy出错的解决方法

    .ERROR Deployer not found: git 执行npm install hexo-deployer-git --save .$ hexo d INFO Deploying: git ...

  6. Linux下面CentOS 7桌面的安装

    搭建本地yum仓库的方法 http://www.cnblogs.com/lql123/p/5952788.html 1.yum grouplist #列出yum仓库里的软件组列表 2.yum grou ...

  7. Javascript学习笔记2.1 Javascript与DOM简介

    DOM(文档对象模型)简介 DOM(文档对象模型)针对HTML和XML文档的一个API. DOM可以将任何HTML或XML文档描绘成由多层节点构成的树形结构,它是中立于平台和语言的接口,允许程序和脚本 ...

  8. iOS沙盒(sandbox)

    iOS沙盒 每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,默认下iOS应用只能访问自己的沙盒 extenaion是iOS8新开放的一种对几个固定系统区域的扩展机制,它可以在一定程度上弥补 ...

  9. CodeForces #368 div2 D Persistent Bookcase DFS

    题目链接:D Persistent Bookcase 题意:有一个n*m的书架,开始是空的,现在有k种操作: 1 x y 这个位置如果没书,放书. 2 x y 这个位置如果有书,拿走. 3 x 反转这 ...

  10. 判断Sql Server2008中ntext不为空

    select * from 表名 where datalength(列名)=0 or datalength(列名) is null