1.Java内置对字符串的支持;
  所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和wstring类实现与C语言兼容和Unicode标准。Java内部通过String类实现对字符串类型的支持。
这意味着:我们可以直接对字符串常量调用和String对象同样的方法:

  //可以再"abc"上直接调用String对象的所有方法
  int length="abc".length();
    以及
  String abc=new String("abc");
  int length=abc.length();

2.Java中的字符串值是constant(常量的)

  这里的意思是字符串类型在创建完成之后,是不能改变其中的值的,从String的成员方法也可以看出没有能改变值的方法接口;并且像"abc",new String("def")中的”abc","def"存放于Java虚拟机中的常量池。

以下的代码中的"abc"存放于常量池中,因此变量a,ab指向的地址均为常量池中同一个"abc"。

public class StringTest {
public static void main(String[] args) {
String a="abc";
String ab="abc";
String abc=new String("abc");
System.out.println(ab==a);
System.out.println(a==abc);
}
}
/*程序输出:
* true
* false
* */

 

  那么动态生成的、可变的字符串又是如何实现的呢?Java中提供StringBuffer和StringBuilder类实现这一需求;Java中字符串连接可以使用“+”操作符; 如:"abc"+"def";这里的内部实现也可以使用StringBuilder类或者StringBuffer类实现;那么StringBuilder和StringBuffer内部又是如何实现呢?是通过字符数组存储字符串。以下是从JDK附带的源码中找到的片段,可以看出StringBuffer内部使用char数组对字符串进行存储,其中的AbstractStringBuilder是StringBuffer的父类:

3.字符串中的编码问题。
  这里要理解两个问题:如何处理源文件中的字符串编码?编译成class文件或者是代码在Java虚拟机运行时字符串是采用什么编码的?
  第一个问题的理解是:源代码中的字符串编码取决于你的IDE或者文本编辑器。如以下的代码是使用GBK编码格式下编辑,然后使用UTF-8和GBK解码打开
//GBK编码格式,使用GBK格式打开

//GBK编码格式,使用UTF-8格式打开,乱码;如果此时系统默认的编码格式不是GBK时,在编译时需要在javac加入"-encoding GBK"参数选项值;

  那么如何处理这种源代码编码的问题呢?答案是在编译器javac的参数选项-encoding中指定,默认这一参数的值是跟系统默认的编码一致。Windows的默认编码一般为GBK (可以通过System.getProperty("file.encoding")获得该值);在系统默认编码为GBK,但是源代码使用UTF-8编码,此时应该使用  javac -encoding UTF-8  进行编译。

  对 ”编译成class文件或者是代码在Java虚拟机运行时字符串是采用什么编码的?“ 这个问题的理解是:首先,Java中的String类型是采用UTF-16编码实现的,也就是不管在源码的编码如何,在Java虚拟机中的字符串都是使用UTF-16编码实现。这意味着只要编译器javac正确的理解了源码文件中字符串的编码,运行时或者class字节码文件中的字符串是独立于源码中的编码格式的。这里我们可以进一步对java中的char基本类型或者Character类进行理解解,这两者内部的编码和java的字符串类型一样,都是基于UTF-16编码实现的,也就是不论‘a','1'这样的字符还是汉字在Java中的长度都是16位。

  并且在String类型中也有着通过指定定字符编码,对底层二进制表示和字符串之间进行转化,也就意味着我们可以正确地读取GBK编码、UTF-8编码或者其他编码的文本文件或者其他输入流将其转化为内存中正确的字符串。

如String类中有如下的方法:
  public String(byte[] bytes, Charset charset);通过指定定字符集编码类型,和相应的byte数组(byte长度为8位)构造字符串;
  public byte[] getBytes(Charset charset);指定字符集编码类型,将字符串转化为byte数组,即字符串的二进制表示。

还有需要注意String的另一个成员方法:

  public byte[] getBytes();这个方法返回的byte数组,所根据的字符集编码是指平台默认的字符集编码,而不一定是UTF-16。

理解Java中的字符串类型的更多相关文章

  1. java中,字符串类型的时间数据怎样转换成date类型。

    将字符串类型的时间转换成date类型可以使用SimpleDateFormat来转换,具体方法如下:1.定义一个字符串类型的时间:2.创建一个SimpleDateFormat对象并设置格式:3.最后使用 ...

  2. 深入理解java中的byte类型

    作者 | 进击的石头--GO! 来源 | https://www.cnblogs.com/zl181015/p/9435035.html#4432849 Java也提供了一个byte数据类型,并且是基 ...

  3. Java中的字符串驻留

    转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = “hello” + “world”;被 ...

  4. 深入学习Java中的字符串,代码点和代码单元

    在Java字符串处理时,在使用length和charAt方法时,应该格外小心,因为length返回的是UTF-16编码表示下的代码单元数量,而非我们所认为的字符的个数,charAt方法返回的是指定位置 ...

  5. 第48篇 说说.Net与Java中的字符串

    原文地址:http://blog.laofu.online/2017/08/18/String-In-dotnet-Java/ Java字符串碰到的问题 在写Java程序碰到一个问题,而正是这个问题引 ...

  6. 深入理解Java中的IO

    深入理解Java中的IO 引言:     对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java >   本文的目录视图如下: ...

  7. 详解Java中的字符串

    字符串常量池详解 在深入学习字符串类之前, 我们先搞懂JVM是怎样处理新生字符串的. 当你知道字符串的初始化细节后, 再去写String s = "hello"或String s ...

  8. 理解Java中字符流与字节流的区别

    1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序 ...

  9. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

随机推荐

  1. 给新手的 10 个有用 Linux 命令行技巧

    我记得我第一次使用 Linux 的时候,我还习惯于 Windows 的图形界面,我真的很讨厌 Linux 终端.那时候我觉得命令难以记忆,不能正确使用它们.随着时间推移,我意识到了 Linux 终端的 ...

  2. 判断数组中有没有某个键 isset 和 array_key_exists 的效率比较

    判断数组中有没有某个键 isset 和 array_key_exists 谁的效率高呢? 使用 array_key_exists 代码如下 结果如下 如果使用 isset 代码如下 结果如下: 很明显 ...

  3. linux中删除目录

    在linux中删除一个目录很简单,很多人还是习惯用rmdir,不过一旦目录非空,就陷入深深的苦恼之中,现在使用rm -rf命令即可解决. 直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目 ...

  4. 动态调用DLL函数有时正常,有时报Access violation的异常

    动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() {     hInst=LoadL ...

  5. Ubuntu 12.04 安装搜狗输入法

    安装指南 Ubuntu / Ubuntu Kylin 14.04 LTS 版本 只需双击下载的 deb 软件包,即可直接安装搜狗输入法. Ubuntu 12.04 LTS 版本 由于 Ubuntu 1 ...

  6. freemarker 自己定义指令

    1 简单介绍 自己定义指令能够使用 macro 指令来定义,这是模板设计者所关心的内容. Java 程序猿若不想在模板中实 现定义指令 ,而是在 Java 语言中实现指令 的定义,这时 能够使用fre ...

  7. 关于AFinal的混淆

    http://blog.csdn.net/aibieqing241/article/details/38979531 我的前个项目中打算引用个框架,于是就看上了AFinal的这个开源库, 感觉用着还不 ...

  8. 在Java项目中整合Scala

    Scala是一个运行在Java JVM上的面向对象的语言.它支持函数编程,在语法上比Java更加灵活,同时通过Akka库,Scala支持强大的基于Actor的多线程编程.具有这些优势,使得我最近很想在 ...

  9. [ES6] 21. ESNext, ES6-Shim & Node

    ES-Next: Esnextis similar to traceur, you can use command line to compile files. Install: npm instal ...

  10. pixel实践

    安装pixel .安装node.js wget http://nodejs.org/dist/v0.6.1/node-v0.6.1.tar.gz 本地测试下载的是这个版本,如果要高版本的话可以找高版本 ...