JAVA基础学习之路(八)[1]String类的基本特点
String类的两种定义方式:
直接赋值
通过构造方法赋值
//直接赋值
public class test2 {
public static void main(String args[]) {
String str = "hello";
System.out.println(str);
}
} //通过构造方法
public class test2 {
public static void main(String args[]) {
String str = new String("hello");
System.out.println(str);
}
}
但是,两种方法却有着极大的区别
主要体现在内存上
一个简单的例子:
public class test1 {
public static void main(String args[]) {
int a = 10;
int b = 10;
String str_1 = "hello";
String str_2 = "hello";
String str_3 = new String("hello");
System.out.println(a==b);
System.out.println(str_1==str_2);
System.out.println(str_1==str_3);
System.out.println(str_2==str_3);
}
} //输出为true true false false
按道理来说,应该是四个true,因为他们的值都是相等的啊.......但是.....

上图解释了两个通过直接赋相同值产生的字符串使用“”==“”为什么返回true。
为什么会全部指向一块堆内存而不是分别指向自己的堆内存呢???
共享设计模式:
在JVM底层有一个对象池,里面有包括String在内的许多对象,当代码之中使用了直接赋值的方式定义了一个String类对象时,会将此字符串使用的匿名对象加入对象池。之后若有采用直接赋值的方式定义字符串,并且赋了相同的值,那么不会开辟新的堆内存空间,而是使用已有的对象(堆内存)进行继续使用。

上图解释了为什么直接赋值和构造方法赋相同的值,然而返回值却为false。因为使用构造方法定义字符串,使用了new关键字,意味着产生一块新的堆内存。那么两种方法各自开辟了一块堆内存,“==”符号对于字符串来说,比较的是地址值。两块堆内存的地址不同,所以返回值为false。
若要比较字符串的内容,而不是地址,应该使用str_a.equals(str_b)
字符串常量就是String类的匿名对象,所谓的直接赋值实际上就是为匿名对象加了一个名字。但是String类的匿名对象是由系统自动生成的,不用用户自己创建
public class test1 {
public static void main(String args[]) {
String str = "hello";
System.out.println("hello".equals(str));
}
}
//返回值为true
tips:
防止空指向异常(使用了未实例化的对象):将字符串写在输入的前面
public class test1 {
public static void main(String args[]) {
String input = null;
System.out.println(input.equals("hello"));
}
}
//Exception in thread "main" java.lang.NullPointerException
at test.test1.main(test1.java:6) 空指向异常
public class test1 {
public static void main(String args[]) {
String input = null;
System.out.println("hello".equals(input));
}
}
//false
两种定义方法的优劣:
直接赋值节约空间
然而构造方法却会产生大量垃圾,如下图:

代码从右向左看,产生的第一块堆内存会成为垃圾
构造方法实例化的方法除了浪费内存外,其定义的对象不会保存在对象池之中,若要保存,需要手动入池(使用inner()方法)
public class test1 {
public static void main(String args[]) {
String str_1 = new String("hello").intern();
String str_2 = "hello";
System.out.println(str_1==str_2);
}
}
//true
返回值为true,证明入池成功。
JAVA基础学习之路(八)[1]String类的基本特点的更多相关文章
- JAVA基础学习之路(三)类定义及构造方法
类的定义及使用 一,类的定义 class Book {//定义一个类 int price;//定义一个属性 int num; public static int getMonney(int price ...
- Java基础系列2:深入理解String类
Java基础系列2:深入理解String类 String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String.主要包括如下的五个内容: Strin ...
- JAVA基础学习之路(一)基本概念及运算符
JAVA基础概念: PATH: path属于操作系统的属性,是系统用来搜寻可执行文件的路径 CALSSPATH: java程序解释类文件时加载文件的路径 注释: 单行注释 // 多行注释 /*... ...
- JAVA基础学习之路(十一)引用传递
引用传递: 不同栈内存可以指向同一块堆内存,不同栈内存可以对一块堆内存进行修改 范例一: class Message { private int num = 10; public Message(in ...
- Java基础篇(02):特殊的String类,和相关扩展API
本文源码:GitHub·点这里 || GitEE·点这里 一.String类简介 1.基础简介 字符串是一个特殊的数据类型,属于引用类型.String类在Java中使用关键字final修饰,所以这个类 ...
- JAVA基础学习之路(九)[2]String类常用方法
字符与字符串: 1.将字符数组变为字符串(构造方法) public String(char[] value) Allocates a new String so that it represents ...
- Java基础学习笔记十八 异常处理
什么是异常?Java代码在运行时期发生的问题就是异常. 在Java中,把异常信息封装成了一个类.当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置.原因等). 异常的继承体系 在 ...
- JAVA基础学习之路(五)数组的定义及使用
什么是数组:就是一堆相同类型的数据放一堆(一组相关变量的集合) 定义语法: 1.声明并开辟数组 数据类型 数组名[] = new 数据类型[长度]: 2.分布完成 声明数组:数据类型 数组名 [] = ...
- JAVA基础学习之路(七)对象数组的定义及使用
两种定义方式: 1.动态初始化: 定义并开辟数组:类名称 对象数组名[] = new 类名称[长度] 分布按成:类名称 对象数组名[] = null: 对象数组名 = new 类名称[长度]: 2 ...
随机推荐
- Lodash数组篇
概念简述 lodash 是一个类库 Lodash 通过降低 array.number.objects.string 等等的使用难度从而让 JavaScript 变得更简单 用法 let _ = re ...
- MySQL优化之Explain命令解读
简述: explain为mysql提供语句的执行计划信息.可以应用在select.delete.insert.update和place语句上.explain的执行计划,只是作为语句执行过程的一个参考, ...
- 搭建Hadoop2.6.0+Spark1.1.0集群环境
前几篇文章主要介绍了单机模式的hadoop和spark的安装和配置,方便开发和调试.本文主要介绍,真正集群环境下hadoop和spark的安装和使用. 1. 环境准备 集群有三台机器: master: ...
- windows用交互式命令执行python程序
1.进入cmd命令 windows+r2.进入盘符,eg:E:3.使用dir命令查看当前文件夹下的所有目录4.使用绝对路径或者相对路径和cd命令直接进入想要到达的文件夹目录(或者使用cd命令一步一步达 ...
- DataSet转换为泛型集合和DataRow 转成 模型类
public static class TransformToList { /// <summary> /// DataSet转换为泛型集合 /// </summary> // ...
- es6-----部分新特性详解
ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony(和谐之意,显然没有跟上我国的步伐,我们已经进入中国梦版本了).上一次标准的制订还是2009年出台 ...
- VUE通过索引值获取数据不渲染的问题
问题:vue里面当通过索引值获取数据时,ajax数据成功返回,但是在火狐下不渲染 解决:
- QK对中断的特殊处理
1.QK的特性 QK(Quntum Kernel)是一个抢占式.基于优先级实时微内核.一个多任务调度器: QK不同于传统的RTOS,是非阻塞的,并且只用了一个stack: 对QK中的任务来说,采用了I ...
- python函数的四种参数传递方式
python中函数传递参数有四种形式 fun1(a,b,c) fun2(a=1,b=2,c=3) fun3(*args) fun4(**kargs) 四种中最常见是前两种,基本上一般点的教程都会涉及, ...
- mfc和qt的区别
注:引用来源 http://wenda.chinabaike.com/b/30934/2013/1208/707410.html QT使用的编译器是MinGW,即Linux下的GCC移植到window ...