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 ...
随机推荐
- datagrid和combobox简单应用
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...
- HDU 2048 神、上帝以及老天爷(错排概率问题)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2048 神.上帝以及老天爷 Time Limit: 2000/1000 MS (Java/Others) ...
- Xcode7解决VVDocumenter 不能使用的方案
Xcode7解决VVDocumenter 不能使用的方案 VVDocumenter-Xcode是Xcode上一款快速添加标准注释,并可以自动生成文档的插件.有了VVDocumenter-Xcode,规 ...
- javaScript 工作必知(十一) 数组常用方法实现
大纲 Array join reverse反转 sort排序 concat 拼接 slice splice 数组 //定义数组 var a = []; //使用Array定义一个数组, var a1 ...
- python对文件进行读写操作
转:http://sucre.iteye.com/blog/704077 ython进行文件读写的函数是open或file file_handler = open(filename,,mode) Ta ...
- linux系统可执行文件添加环境变量使其跨终端和目录执行
在命令行终端输入:echo $PATH 回车可打印出PATH变量对应的路径 现有一可执行文件qtFirstC,文件所在目录为:/home/lolors/qtFirstC 此时test只能在此目录下运行 ...
- MapReduce清洗日志数据统计PV量
package mapreduce.webpv; import java.io.IOException; import org.apache.commons.lang.StringUtils; imp ...
- Vi中进行多行指定内容替换
1.先按Esc进入命令模式,然后在打出‘:’(英文输入模式下) 2.输入格式: 首行数,末行数s/要替换的字符串/替换的字符串/g (不加g只替换每行的一个要替换的字符串,后面的不会替换) e ...
- Go语言中的变量
1 概述 变量(Variable)是程序运行过程中,内容可以变化(修改)的量,变量的功能是存储用户的数据,是计算机语言中能储存计算结果或能表示值抽象概念.变量,是通过变量的标识符定位值的过程.变量的内 ...
- Noip 2011 Day 1 & Day 2
Day 1 >>> T1 >> 水题一道 . 我们只需要 for 一遍 , 由于地毯是从下往上铺的 , 我们只需要记录该位置最上面的地毯的编号 , 每一次在当前地 ...