Module java.base
Package java.nio.charset

Class Charset

java.lang.Object
java.nio.charset.Charset
所有已实现的接口:
Comparable<Charset>

public abstract class Charset extends Object implements Comparable<Charset>
16位Unicode代码单元序列和字节序列之间的命名映射。此类定义了用于创建解码器和编码器以及检索与字符集相关联的各种名称的方法。此类的实例是不可变的。

此类还定义了用于测试特定字符集是否受支持、按名称查找字符集实例以及构造包含当前Java虚拟机中可用支持的每个字符集的映射的静态方法。可以通过在CharsetProvider类中定义的服务提供程序接口添加对新字符集的支持。

此类中定义的所有方法都可以安全地供多个并发线程使用。

字符集名称

字符集由以下字符组成的字符串命名:

  • 大写字母'A''Z''\u0041''\u005a'),
  • 小写字母'a''z''\u0061''\u007a'),
  • 数字'0''9''\u0030''\u0039'),
  • 破折号字符'-''\u002d',HYPHEN-MINUS),
  • 加号字符'+''\u002b',PLUS SIGN),
  • 句点字符'.''\u002e',FULL STOP),
  • 冒号字符':''\u003a',COLON),和
  • 下划线字符'_''\u005f',LOW LINE)。
字符集名称必须以字母或数字开头。空字符串不是合法的字符集名称。字符集名称不区分大小写;即,在比较字符集名称时始终忽略大小写。字符集名称通常遵循RFC 2278:IANA字符集注册程序中记录的约定。

每个字符集都有一个规范名称,也可能有一个或多个别名。规范名称由此类的name方法返回。按照惯例,规范名称通常为大写。字符集的别名由aliases方法返回。

一些字符集具有一个历史名称,用于与Java平台先前版本兼容。 字符集的历史名称是其规范名称或其别名之一。字符集的历史名称由InputStreamReaderOutputStreamWriter类的getEncoding()方法返回。

如果Java平台的实现支持IANA字符集注册表中列出的字符集,则其规范名称必须是注册表中列出的名称。许多字符集在注册表中有多个名称,此时注册表将一个名称标识为MIME首选。如果字符集有多个注册表名称,则其规范名称必须是MIME首选名称,而注册表中的其他名称必须是有效的别名。如果支持的字符集未在IANA注册表中列出,则其规范名称必须以字符串"X-""x-"之一开头。

IANA字符集注册表会随时间而更改,因此特定字符集的规范名称和别名也可能随时间而更改。为确保兼容性,建议永远不要从字符集中删除别名,并且如果更改字符集的规范名称,则应将其以前的规范名称作为别名。

标准字符集

Java平台的每个实现都必须支持以下标准字符集。请查阅您的实现的发布文档,以查看是否支持其他字符集。这些可选字符集的行为可能在不同实现之间有所不同。

标准字符集描述
字符集 描述
US-ASCII 七位ASCII,又名ISO646-US,又名Unicode字符集的基本拉丁区块
ISO-8859-1   ISO拉丁字母表1,又名ISO-LATIN-1
UTF-8 八位UCS转换格式
UTF-16BE 十六位UCS转换格式,大端字节顺序
UTF-16LE 十六位UCS转换格式,小端字节顺序
UTF-16 十六位UCS转换格式,字节顺序由可选的字节顺序标记标识

UTF-8字符集由RFC 2279指定;其基础的转换格式在ISO 10646-1的修订2中指定,并且还在Unicode标准中描述。

UTF-16字符集由RFC 2781指定;其基础的转换格式在ISO 10646-1的修订1中指定,并且还在Unicode标准中描述。

UTF-16字符集使用十六位数量,因此对字节顺序敏感。在这些编码中,流的字节顺序可以通过Unicode字符'\uFEFF'表示的初始字节顺序标记来指示。字节顺序标记的处理如下:

  • 在解码时,UTF-16BEUTF-16LE字符集将初始字节顺序标记解释为一个ZERO-WIDTH NON-BREAKING SPACE;在编码时,它们不会写入字节顺序标记。

  • 在解码时,UTF-16字符集将输入流开头的字节顺序标记解释为流的字节顺序,但如果没有字节顺序标记,则默认为大端;在编码时,它使用大端字节顺序并写入大端字节顺序标记。

无论如何,在输入序列的第一个元素之后出现的字节顺序标记都不会被省略,因为相同的代码用于表示ZERO-WIDTH NON-BREAKING SPACE

每个Java虚拟机实例都有一个默认字符集,除非以实现特定的方式更改,否则为UTF-8。有关更多详细信息,请参阅defaultCharset()

StandardCharsets类为每个标准字符集定义了常量。

术语

此类的名称取自RFC 2278中使用的术语。在该文档中,字符集被定义为一个或多个编码字符集和字符编码方案的组合。(此定义令人困惑;其他一些软件系统将字符集定义为编码字符集的同义词。)

编码字符集是一组抽象字符与一组整数之间的映射。US-ASCII、ISO 8859-1、JIS X 0201和Unicode是编码字符集的示例。

一些标准已经定义了字符集,仅仅是一组抽象字符而没有关联的编号。字母表就是这种字符集的示例。然而,在实践中很少使用字符集编码字符集之间微妙的区别;前者已经成为后者的简称,包括在Java API规范中。

字符编码方案是一个或多个编码字符集与一组八位(八位字节)序列之间的映射。UTF-8、UTF-16、ISO 2022和EUC是字符编码方案的示例。编码方案通常与特定的编码字符集相关联;例如,UTF-8仅用于编码Unicode。然而,一些方案与多个编码字符集相关联;例如,EUC可以用于对各种亚洲编码字符集中的字符进行编码。

当编码字符集专门与单个字符编码方案一起使用时,相应的字符集通常以编码字符集的名称命名;否则,字符集通常以编码方案的名称以及可能是其支持的编码字符集的区域设置命名。因此,US-ASCII既是编码字符集的名称,也是编码它的字符集的名称,而EUC-JP是编码JIS X 0201、JIS X 0208和JIS X 0212编码字符集的日语语言的字符集的名称。

Java编程语言的本机字符编码是UTF-16。因此,Java平台中的字符集定义了十六位UTF-16代码单元序列(即,char序列)和字节序列之间的映射。

自1.4版本开始
1.4
外部规范
参见:
  • Constructor Details

    • Charset

      protected Charset(String canonicalName, String[] aliases)
      使用给定的规范名称和别名集初始化新的字符集。
      参数:
      canonicalName - 此字符集的规范名称
      aliases - 此字符集的别名数组,如果没有别名则为null
      抛出:
      IllegalCharsetNameException - 如果规范名称或任何别名不合法
  • Method Details

    • isSupported

      public static boolean isSupported(String charsetName)
      告诉是否支持命名字符集。
      参数:
      charsetName - 请求的字符集名称;可以是规范名称或别名
      返回:
      如果当前Java虚拟机中可用于命名字符集的支持,则返回true
      抛出:
      IllegalCharsetNameException - 如果给定的字符集名称不合法
      IllegalArgumentException - 如果给定的charsetName为null
    • forName

      public static Charset forName(String charsetName)
      返回命名字符集的字符集对象。
      参数:
      charsetName - 请求的字符集名称;可以是规范名称或别名
      返回:
      命名字符集的字符集对象
      抛出:
      IllegalCharsetNameException - 如果给定的字符集名称不合法
      IllegalArgumentException - 如果给定的charsetName为null
      UnsupportedCharsetException - 如果在此Java虚拟机实例中没有为命名字符集提供支持
    • forName

      public static Charset forName(String charsetName, Charset fallback)
      返回命名字符集的字符集对象。如果命名字符集的字符集对象不可用或charsetName不是合法字符集名称,则返回fallback
      参数:
      charsetName - 请求的字符集名称;可以是规范名称或别名
      fallback - 如果命名字符集的字符集对象不可用或charsetName不是合法字符集名称,则返回的备用字符集。可以为null
      返回:
      命名字符集的字符集对象,或者如果命名字符集的字符集对象不可用或charsetName不是合法字符集名称,则返回fallback
      抛出:
      IllegalArgumentException - 如果给定的charsetNamenull
      自1.8版本开始
      18
    • availableCharsets

      public static SortedMap<String,Charset> availableCharsets()
      构造一个从规范字符集名称到字符集对象的排序映射。

      此方法返回的映射将为当前Java虚拟机中可用的每个字符集条目。如果两个或更多支持的字符集具有相同的规范名称,则生成的映射将只包含其中一个;不指定将包含哪一个。

      此方法的调用和随后使用生成的映射可能导致耗时的磁盘或网络I/O操作。此方法适用于需要枚举所有可用字符集的应用程序,例如允许用户选择字符集。此方法不被forName方法使用,后者使用高效的增量查找算法。

      如果当前Java虚拟机动态提供了新的字符集提供程序,则此方法可能在不同时间返回不同的结果。在没有这些更改的情况下,此方法返回的字符集正是可以通过forName方法检索的字符集。

      返回:
      一个不可变的、不区分大小写的从规范字符集名称到字符集对象的映射
    • defaultCharset

      public static Charset defaultCharset()
      返回此Java虚拟机的默认字符集。

      默认字符集是UTF-8,除非以实现特定的方式更改。

      实现注意:
      实现可以通过命令行上的系统属性file.encoding覆盖默认字符集。如果值为COMPAT,则默认字符集源自native.encoding系统属性,这通常取决于底层操作系统的区域设置和字符集。
      返回:
      默认字符集的字符集对象
      自1.5版本开始
      1.5
      参见:
    • name

      public final String name()
      返回此字符集的规范名称。
      返回:
      此字符集的规范名称
    • aliases

      public final Set<String> aliases()
      返回一个包含此字符集别名的集合。
      返回:
      一个不可变的此字符集别名的集合
    • displayName

      public String displayName()
      返回此字符集在默认区域设置下的人类可读名称。

      此方法的默认实现简单地返回此字符集的规范名称。此类的具体子类可以重写此方法以提供本地化的显示名称。

      返回:
      默认区域设置下此字符集的显示名称
    • isRegistered

      public final boolean isRegistered()
      告诉这个字符集是否在IANA字符集注册表中注册。
      返回:
      如果此字符集已知由其实现者注册到IANA,则返回true
      外部规范
    • displayName

      public String displayName(Locale locale)
      返回给定区域设置下此字符集的人类可读名称。

      此方法的默认实现简单地返回此字符集的规范名称。此类的具体子类可以重写此方法以提供本地化的显示名称。

      Parameters:
      locale - The locale for which the display name is to be retrieved
      Returns:
      The display name of this charset in the given locale
    • contains

      public abstract boolean contains(Charset cs)
      Tells whether or not this charset contains the given charset.

      A charset C is said to contain a charset D if, and only if, every character representable in D is also representable in C. If this relationship holds then it is guaranteed that every string that can be encoded in D can also be encoded in C without performing any replacements.

      That C contains D does not imply that each character representable in C by a particular byte sequence is represented in D by the same byte sequence, although sometimes this is the case.

      Every charset contains itself.

      This method computes an approximation of the containment relation: If it returns true then the given charset is known to be contained by this charset; if it returns false, however, then it is not necessarily the case that the given charset is not contained in this charset.

      参数:
      cs - 给定的字符集
      返回:
      true 如果给定的字符集包含在此字符集中
    • newDecoder

      public abstract CharsetDecoder newDecoder()
      构造此字符集的新解码器。
      返回:
      此字符集的新解码器
    • newEncoder

      public abstract CharsetEncoder newEncoder()
      构造此字符集的新编码器。
      返回:
      此字符集的新编码器
      抛出:
      UnsupportedOperationException - 如果此字符集不支持编码
    • canEncode

      public boolean canEncode()
      告知此字符集是否支持编码。

      几乎所有字符集都支持编码。主要例外是特殊用途的自动检测字符集,其解码器可以通过检查输入字节序列来确定正在使用的多个可能的编码方案之一。这些字符集不支持编码,因为无法确定应在输出上使用哪种编码。此类字符集的实现应重写此方法以返回false

      返回:
      true 如果且仅如果此字符集支持编码
    • decode

      public final CharBuffer decode(ByteBuffer bb)
      将此字符集中的字节解码为Unicode字符的便捷方法。

      对字符集cs调用此方法将返回与表达式相同的结果

          cs.newDecoder()
            .onMalformedInput(CodingErrorAction.REPLACE)
            .onUnmappableCharacter(CodingErrorAction.REPLACE)
            .decode(bb);
      
      除了它可能更有效,因为它可以在连续调用之间缓存解码器。

      此方法始终使用此字符集的默认替换字节数组替换格式不正确的输入和无法映射的字符序列。为了检测这样的序列,请直接使用CharsetDecoder.decode(java.nio.ByteBuffer)方法。

      参数:
      bb - 要解码的字节缓冲区
      返回:
      包含解码字符的字符缓冲区
    • encode

      public final ByteBuffer encode(CharBuffer cb)
      将Unicode字符编码为此字符集中的字节的便捷方法。

      对字符集cs调用此方法将返回与表达式相同的结果

          cs.newEncoder()
            .onMalformedInput(CodingErrorAction.REPLACE)
            .onUnmappableCharacter(CodingErrorAction.REPLACE)
            .encode(bb);
      
      除了它可能更有效,因为它可以在连续调用之间缓存编码器。

      此方法始终使用此字符集的默认替换字符串替换格式不正确的输入和无法映射的字符序列。为了检测这样的序列,请直接使用CharsetEncoder.encode(java.nio.CharBuffer)方法。

      参数:
      cb - 要编码的字符缓冲区
      返回:
      包含编码字符的字节缓冲区
    • encode

      public final ByteBuffer encode(String str)
      将字符串编码为此字符集中的字节的便捷方法。

      对字符集cs调用此方法将返回与表达式相同的结果

          cs.encode(CharBuffer.wrap(s));
      
      参数:
      str - 要编码的字符串
      返回:
      包含编码字符的字节缓冲区
    • compareTo

      public final int compareTo(Charset that)
      比较此字符集与另一个字符集。

      字符集按其规范名称排序,不考虑大小写。

      指定者:
      compareTo 在接口 Comparable<Charset>
      参数:
      that - 要比较的字符集
      返回:
      一个负整数、零或正整数,表示此字符集小于、等于或大于指定的字符集
    • hashCode

      public final int hashCode()
      为此字符集计算哈希码。
      覆盖:
      hashCode 在类 Object
      返回:
      一个整数哈希码
      另请参阅:
    • equals

      public final boolean equals(Object ob)
      告知此对象是否等于另一个对象。

      如果两个字符集具有相同的规范名称,则它们才相等。字符集永远不等于任何其他类型的对象。

      覆盖:
      equals 在类 Object
      参数:
      ob - 要比较的引用对象
      返回:
      true 如果且仅如果此字符集等于给定对象
      另请参阅:
    • toString

      public final String toString()
      返回描述此字符集的字符串。
      覆盖:
      toString 在类 Object
      返回:
      描述此字符集的字符串