String是什么

String字符串,是一种引用数据类型,并不是基础数据类型。

对于基础数据类型和引用数据类型的区别:

基础数据类型,在创建时直接将值存放在栈内存中。

引用数据类型,在创建时栈内存中存放一个引用,这个引用存放的是堆内存的位置,而堆内存中就是存放具体的值。

举例说明:

假如String对象是一个储物柜,在使用储物柜时(相当于新建一个String对象),

我们需要会得到一张记着储物柜的小票(小票相当于栈内存空间,小票上保存引用),

凭借这张小票就可以找到储物柜,然后拿到储物柜中存放的东西(储物柜相当于堆内存空间,可以根据引用去得到堆内存中的值)。

对于基础数据类型,则是直接将值写在小票上。

String的底层数据结构

String的底层实现是字符数组,这一点可以在源码中看到,

其中属性 private final char value[]; 就是用来存储String的值,

以下是String类的部分源码:

 public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[]; /** Cache the hash code for the string */
private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

String类被final修饰,则表示String类不可以被继承。

String类的value属性使用了 final 进行修饰,则表示value是一个常量,常量不可以更改。

String对象的重新赋值

String类的源码中可以看到String类的value属性使用了 final 进行修饰,既然是常量。

在发生对象需要重新赋值的时候,String的做法是,将String对象的栈内存与堆内存的引用断开。

再将栈内存中的引用指向新的堆内存空间。

本质上就是新建一个String对象。

由此可以引发一个问题,如果代码中频繁出现对String对象的重新赋值意味着会有大量的堆内存被弃用。

这部分被弃用的堆内存空间只能通过垃圾回收机制进行回收,这会降低内存的利用率。(浪费内存是一方面,另一方面垃圾回收也会耗费资源。此问题在面试中出现的概率比较高)

这个问题可以通过使用StringBuffer或者StringBuilder来解决(StringBuffer和StringBuilder会在接下来的文章进行介绍)。

以下是《Java开发实战经典》一书中的示例:

String对象的比较

比较方式分为两种(自定义比较方法除外):

a.双等号(==):双等号的判断依据是对象的堆内存地址是否相同。(用上面储物柜的例子就是同一个储物柜,当然放的是同样的东西)

b.使用方法equals(Object anObject):方法比较的是对象的取值。

String类中equals(Object anObject)方法源码:

     public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) { //通过while循环比较字符数组中的值
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

以下是代码示例:

public class TestString {
public static void main(String[] args) {
String str1 = "a";
String str2 = "a";
String str3 = new String("a"); //使用new关键词创建String对象
String str4 = "b"; System.out.println("str1 == str2: "+(str1 == str2));
System.out.println("str1 equals str2: "+(str1.equals(str2)));
System.out.println("str1 == str3: "+(str1 == str3));
System.out.println("str1 equals str3: "+(str1.equals(str3)));
System.out.println("str1 == str4: "+(str1 == str4));
}
}

控制台结果:

str1  ==    str2: true
str1 equals str2: true
str1 == str3: false
str1 equals str3: true
str1 == str4: false

通过 str1 == str2: true 结果得出的结论:

String类在不使用new 关键词来新建对象时,如果str1 和 str2 的取值相同,

并不会为str1 和 str2 分别开辟堆内存空间,而是将str1 和 str2同时指向同一个堆内存,减少内存浪费。

String类常用方法

以下是《Java开发实战经典》一书中表格:

结语

纸上得来终觉浅,绝知此事要躬行。

String类中的内容很多,单构造方法就是十多种。

虽然内容多,但是难度都不高可能花看一个小视频的时间能看完。

这里对String类进行简单的介绍。

String 字符串对象的更多相关文章

  1. JS对象 String 字符串对象定义字符串的方法就是直接赋值。比如: var mystr = "I love JavaScript!"

    String 字符串对象 在之前的学习中已经使用字符串对象了,定义字符串的方法就是直接赋值.比如: var mystr = "I love JavaScript!" 定义mystr ...

  2. Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法

    首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的: 第一种方法: jobject  NewObject(jclass clazz  , jmethodI ...

  3. 第七天:JS内置对象-String字符串对象

    1.String对象  String对象用于处理已有的字符串 字符串可以使用双引号或单引号 String对象有一些常用的方法和属性,例如length 示例代码: <!DOCTYPE html&g ...

  4. js String字符串对象常见方法总结

    String对象常用来保存文本形式的数据. 其转化方法有二种: String(s) new String(s) String对象方法有: charAt() charCodeAt() concat() ...

  5. JavaScript的内置对象(Date日期+string字符串)基础语法总结

    1.Date日期对象可以储存任意一个日期,并且可以精确到毫秒数(1/1000 秒). 1)定义一个时间对象 : var Udate=new Date(); //注意:使用关键字new,Date()的首 ...

  6. javascript字符串对象

    String字符串对象 1. 字符串粗体展示: var a = "陈冠希喜欢拍电影";   document.writeln(a.bold()+"<br/>& ...

  7. javascript中的字符串对象和数组对象

    1.javascript的对象的概念 在javascript中,除了null和undefined以处,其他的数据类型都被定义成了对象 也可以用创建对象的方法定义变量,string,math,array ...

  8. javascript中的字符串对象

    1.javascript的对象的概念 在javascript中,除了null和undefined以处,其他的数据类型都被定义成了对象 也可以用创建对象的方法定义变量,string,math,array ...

  9. JavaScript 字符串(String) 对象

    JavaScript 字符串(String) 对象 String 对象用于处理已有的字符块. JavaScript 字符串 一个字符串用于存储一系列字符就像 "John Doe". ...

随机推荐

  1. python_way ,day22 tonardo,jsonp

    python_way day22 1.tonardo 2.cookie 3.api认证 一.tonardo: a.tonardo 初识 #!/usr/bin/env python3# Created ...

  2. centos7.2下快速安装zabbix4.0

    本笔记是基于CentOS 7.2下最小化安装的操作系统搭建的Zabbix4.0环境,主要用于做一些企业路由器和交换机等设备的运行状态监控. 1.安装epel源 yum -y install epel- ...

  3. 7-vim-移动命令-02-行数跳转和上下翻页

    1.行数跳转 命令 英文 功能 gg go 文件顶部 G GO 文件尾部 数字gg   移动到数字对应行数 数字G   移动到数字对应行数 :数字   移动到数字对应行数 2.屏幕移动 命令 英文 功 ...

  4. 微信1.8.6.1 SDK 无法授权登录解决办法

    我用的cocos2d-lua 3.9 项目打包 调用微信授权登录的时候 授权登录接口一直抛异常导致微信都无法拉起来 按照官网配置了universal link (这个也搞了很长时间jason 配置文件 ...

  5. ubuntu QT安装以及配置交叉编译环境

    我的环境:ubuntu14.04  64位 1.下载Qt: 上网搜索 qt-opensource-linux-x64-5.3.0.run下载有好多百度云盘 要么在官网下载追新版本http://down ...

  6. hdu5421 Victor and String 回文树(前后插入)

    题目传送门 题意:对一个字符串支持四种操作,前插入字符,后插入字符,询问本质不同的回文串数量和所有回文串的数量. 思路: 就是在普通回文树的基础上,维护suf(最长回文后缀)的同时再维护一个pre(最 ...

  7. 笔记55 Mybatis快速入门(六)

    相关概念介绍(一) 1.日志 有时候需要打印日志,知道mybatis执行了什么样的SQL语句,以便进行调试.这时,就需要开启日志,而mybatis自身是没有带日志的,使用的都是第三方日志,这里介绍如何 ...

  8. *** stack smashing detected ***: ./server terminated

    该类错误是修改了返回指针,一般是由于 1. 数组越界赋值.(数组没有边界检查)int a[8]; a[8],a[9],a[-1]..都能正常编译,连接,运行时可能出错. 2.使用 strcpy等不安全 ...

  9. typescript + vue开发遇到的坑

    1,错误 :TS2304: Cannot find name 'require' 在ts使用nodejs,没有安装nodejs的TypeScript定义类型 ,使用require报的错 解决方法:如果 ...

  10. 解析Mybatis入门第一天

    MyBatis是一个基于Java的持久层框架,内部对JDBC做了封装,使开发者只需要关注SQL语句,而不用关注JDBC的代码,使开发变得更加的简单. MyBatis通过XML或者注解的方式将要执行的各 ...