标签分类
技术文章
当前位置:主页 > 计算机编程 > java > Java语言中一个字符占几个字节

Java语言中一个字符占的字节数详解

  • 发布时间:
  • 作者:码农之家原创
  • 点击:150

Java语言中一个字符占几个字节

这篇文章主要知识点是关于Java,语言,字符,字节数,Java语言中一个字符占几个字节,的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

Head First Java
Head First Java中文影印版
  • 类型:Java学习大小:48.8 MB格式:PDF出版:中国电力出版社作者:塞若
立即下载

题主要区分清楚内码(internal encoding)和外码(external encoding)就好了。

内码是程序内部使用的字符编码,特别是某种语言实现其char或String类型在内存里用的内部编码;
外码是程序与外部交互时外部使用的字符编码。“外部”相对“内部”而言;不是char或String在内存里用的内部编码的地方都可以认为是“外部”。例如,外部可以是序列化之后的char或String,或者外部的文件、命令行参数之类的。

Java语言规范规定,Java的char类型是UTF-16的code unit,也就是一定是16位(2字节);

char, whose values are 16-bit unsigned integers representing UTF-16 code units (§3.1).

然后字符串是UTF-16 code unit的序列:

The Java programming language represents text in sequences of 16-bit code units, using the UTF-16 encoding.

这样,Java规定了字符的内码要用UTF-16编码。或者至少要让用户无法感知到String内部采用了非UTF-16的编码。

另举一例:

Java标准库实现的对char与String的序列化规定使用UTF-8作为外码。Java的Class文件中的字符串常量与符号名字也都规定用UTF-8编码。这大概是当时设计者为了平衡运行时的时间效率(采用定长编码的UTF-16)与外部存储的空间效率(采用变长的UTF-8编码)而做的取舍。

首先,你所谓的“字符”具体指什么呢?

如果你说的“字符”就是指 Java 中的 char,那好,那它就是 16 位,2 字节。

如果你说的“字符”是指我们用眼睛看到的那些“抽象的字符”,那么,谈论它占几个字节是没有意义的。

具体地讲,脱离具体的编码谈某个字符占几个字节是没有意义的。

就好比有一个抽象的整数“42”,你说它占几个字节?这得具体看你是用 byte,short,int,还是 long 来存它。用 byte 存就占一字节,用 short 存就占两字节,int 通常是四字节,long 通常八字节。当然,如果你用 byte,受限于它有限的位数,有些数它是存不了的,比如 256 就无法放在一个 byte 里了。

字符是同样的道理,如果你想谈“占几个字节”,就要先把编码说清楚。

同一个字符在不同的编码下可能占不同的字节。

就以你举的“字”字为例,“字”在 GBK 编码下占 2 字节,在 UTF-16 编码下也占 2 字节,在 UTF-8 编码下占 3 字节,在 UTF-32 编码下占 4 字节。

不同的字符在同一个编码下也可能占不同的字节。

“字”在 UTF-8 编码下占3字节,而“A”在 UTF-8 编码下占 1 字节。(因为 UTF-8 是变长编码)
而 Java 中的 char 本质上是 UTF-16 编码。而 UTF-16 实际上也是一个变长编码(2 字节或 4字节)。

如果一个抽象的字符在 UTF-16 编码下占 4 字节,显然它是不能放到 char 中的。换言之, char 中只能放 UTF-16 编码下只占 2 字节的那些字符。

而 getBytes 实际是做编码转换,你应该显式传入一个参数来指定编码,否则它会使用缺省编码来转换。

你说“ new String("字").getBytes().length 返回的是3 ”,这说明缺省编码是 UTF-8.如果你显式地传入一个参数,比如这样“ new String("字").getBytes("GBK").length ”,那么返回就是 2.

你可以在启动 JVM 时设置一个缺省编码,

假设你的类叫 Main,那么在命令行中用 java 执行这个类时可以通过 file.encoding 参数设置一个缺省编码。比如这样:java -Dfile.encoding=GBK Main这时,你再执行不带参数的 getBytes() 方法时,new String("字").getBytes().length 返回的就是 2 了,因为现在缺省编码变成 GBK 了。当然,如果这时你显式地指定编码,new String("字").getBytes("UTF-8").length 返回的则依旧是 3

否则,会使用所在操作系统环境下的缺省编码。

通常,Windows 系统下是 GBK,Linux 和 Mac 是 UTF-8.但有一点要注意,在 Windows 下使用 IDE 来运行时,比如 Eclipse,如果你的工程的缺省编码是 UTF-8,在 IDE 中运行你的程序时,会加上上述的 -Dfile.encoding=UTF-8 参数,这时,即便你在 Windows 下,缺省编码也是 UTF-8,而不是 GBK。

由于受启动参数及所在操作系统环境的影响,不带参数的 getBytes 方法通常是不建议使用的,最好是显式地指定参数以此获得稳定的预期行为。

以上所述是小编给大家介绍的Java语言中一个字符占几个字节详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对码农之家网站的支持!

以上就是本次给大家分享的全部知识点内容总结,大家还可以在下方相关文章里找到儿童python编程入门书籍推、 vue项目中使用md5加密以及、 解决axios.interceptors.respon、 等java文章进一步学习,感谢大家的阅读和支持。

上一篇:SpringBoot系列教程JPA基础环境搭建的步骤

下一篇:Java编程实现高斯模糊和图像的空间卷积的实例讲解

展开 +

收起 -

学习笔记
网友NO.824795

Java中的字节流文件读取教程(二)

接着上篇文章,我们继续来学习 Java 中的字节流操作。 装饰者缓冲流 BufferedInput/OutputStream 装饰者流其实是基于一种设计模式「装饰者模式」而实现的一种文件 IO 流,而我们的缓冲流只是其中的一种,我们一起来看看。 在这之前,我们使用的文件读写流 FileInputStream 和 FileOutputStream 都是一个字节一个字节的从磁盘读取或写入,非常耗时。 而我们的缓冲流可以预先从磁盘一次性读出指定容量的字节数到内存中,之后的读取操作将直接从内存中读取,提高效率。下面我们一起看看缓冲流的具体实现情况: 依然先以 BufferedInputStream 为例,我们简单提一下它的几个核心属性: private static int DEFAULT_BUFFER_SIZE = 8192; protected volatile byte buf[]; private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; protected int count; protected int pos; protected int markpos = -1; protected int marklimit; buf 就是用于缓冲读的字节数组,它的值将随着流的读取而不停的被填充,继而后续的读操作可以直接基于这个缓冲数组。 DEFAULT_BUFFER_SIZE 规定了默认缓冲区的大小,即 buf 的数组长度。MAX_BUFFER_SIZE 指明了缓冲区的上限。 count 指向缓冲数组中最后一个有效字节索引后一位。pos 指向下一个待读取的字节索引位置。 markpos 和 marklimit 用于重复读操作。 接着我们看看 BufferedInputStream 的几个示例……

网友NO.445767

Java中的字节流文件读取教程(一)

前言 上篇文章我们介绍了抽象化磁盘文件的 File 类型,它仅仅用于抽象化描述一个磁盘文件或目录,却不具备访问和修改一个文件内容的能力。 Java 的 IO 流就是用于读写文件内容的一种设计,它能完成将磁盘文件内容输出到内存或者是将内存数据输出到磁盘文件的数据传输工作。 Java IO 流的设计并不是完美的,设计了大量的类,增加了我们对于 IO 流的理解,但无外乎为两大类,一类是针对二进制文件的字节流,另一类是针对文本文件的字符流。而本篇我们就先来学习有关字节流的相关类型的原理以及使用场景等细节,主要涉及的具体流类型如下: 基类字节流 Input/OutputStream InputStream 和 OutputStream 分别作为读字节流和写字节流的基类,所有字节相关的流都必然继承自他们中任意一个,而它们本身作为一个抽象类,也定义了最基本的读写操作,我们一起来看看: 以 InputStream 为例: public abstract int read() throws IOException; 这是一个抽象的方法,并没有提供默认实现,要求子类必须实现。而这个方法的作用就是为你返回当前文件的下一个字节。 当然,你也会发现这个方法的返回值是使用的整型类型「int」来接收的,为什么不用「byte」? 首先,read 方法返回的值一定是一个八位的二进制,而一个八位的二进制可以取值的值区间为:……

网友NO.884039

通过字节码看java中this的隐式传参详解

前言 从字节码看java中 this 隐式传参具体体现(和python中的self如出一辙,但是比python中藏得更深),也发现了 static 与 非 static 方法的区别所在! static与非static方法都是存储java的方法区。在static 方法中,没有this引用,因此无法使用当前类中所定义的变量,而非static方法则会默认传入this。 概述 this关键字,是一个隐式参数,另外一个隐式参数是super。 this用于方法里面,用于方法外面无意义。 this关键字一般用于set方法和构造方法中。 我们今天就从另一个角度来真实看一下这个答案吧! 来个例子,并将其反编译为可视代码: public class Hello { private final int ii; public Hello(int a) { ii = a; } public static void main(String[] args) throws Exception { sayHelloStatic("ok"); } public void sayHello(String word) { System.out.println("hello, " + word); } public static void sayHelloStatic(String word) { System.out.println("static hello, " + word); }} 反汇编命令: javap -verbose Hello.class 反汇编结果: Classfile /D:/xx/target/classes/com/xx/api/Hello.class Last modified 2018-11-8; size 1069 bytes MD5 checksum 9d39cd9d4e95588a73c059a4e69f01e8 Compiled from "Hello.java"public class com.xx.api.Hello minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPERConstant pool: #1 = Methodref #14.#38 // java/lang/Object."init":()V #2 = Fieldref #13.#39 // com/xx/api/Hello.ii:I #3 = String #40 // ok #4 = Met……

网友NO.588314

java处理字节的常用工具类

处理字节的常用工具类方法,供大家参考,具体内容如下 package com.demo.utils;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.nio.charset.Charset;import java.util.Arrays;/** * 处理字节的常用工具类方法 * @author dongyangyang * @Date 2017/3/13 12:31 * @Version 1.0 * */public class ByteUtils { /** * 构造新字节时需要与的值表 */ private static final byte[] BUILD_BYTE_TABLE = new byte[] { (byte) 128, (byte) 64, (byte) 32, (byte) 16, (byte) 8, (byte) 4, (byte) 2, (byte) 1 }; private ByteUtils() {} /** * short转换到字节数组 * * @param number * 需要转换的数据。 * @return 转换后的字节数组。 */ public static byte[] shortToByte(short number) { byte[] b = new byte[2]; for (int i = 1; i = 0; i--) { b[i] = (byte) (number % 256); number = 8; } return b; } /** * 字节到short转换 * * @param b * short的字节数组 * @return short数值。 */ public static short byteToShort(byte[] b) { return (short) ((((b[0] lt; 8) | b[1] } /** * 整型转换到字节数组 * * @param number * 整形数据。 * @return 整形数据的字节数组。 */ public static byte[] intToByte(int number) { byte[] b = new byte[4]; for (int i = 3; i = 0; i--) { b[i] = (byte) (number % 256); number = 8; } return b; } /** * 字节数组到整型转换 * * @param b * 整形数据的字节数组。 * @return 字节数组转换……

<
1
>

Copyright 2018-2019 xz577.com 码农之家

版权责任说明