1-18String类简介
字符串(String)的不可变性
String类在java.lang包下面,是Object类的直接子类,通过API或者源码可以看到,String类是final修饰的,这说明String类不能被继承。
字符串一旦创建好之后,里面的内容是不能被修改的,jvm会将双引号””中的内容存放在字符串常量池里面,常量池中的对象内容是不可修改的。
String s1 = "monkey1024";
String s2 = "monkey1024";
s1 = "good";
上面代码中,创建s1时,jvm会在常量池中创建一个monkey1024字符串对象,创建s2时,jvm会去常量池中搜索,此时常量池中有monkey024,所以就不创建了,直接让s2指向之前创建的monkey1024。当执行到最后一行时,jvm会在常量池中创建一个good,然后让s1指向这个good,而不是将常量池中的monkey1024修改为good,所以说常量池中的对象内容是不可修改的。

字符串为什么被设计成不可变的?
还是上面的代码
String s1 = "monkey1024";
String s2 = "monkey1024";
s1 = "good";
String是引用数据类型,s1和s2指向的是同一块内存区域。如果String类型是可变的,那上面代码的第三行的s1的修改就会导致s2变化,但这可能并不是程序员的本意。
String的两种创建方式及区别
可以使用下面两种方式创建String类型的对象:
String s3 = "hello";
String s4 = new String("monkey");
这两种方式的区别:
s3:系统会在常量池里面创建一个hello的字符串对象。
s4:系统会在常量池里面创建一个monkey字符串对象,然后在堆内存里面再创建一个monkey字符串对象。
请看下面程序的打印结果:
String s3 = new String("monkey");
String s4 = new String("monkey");
String s5 = "hello";
String s6 = "hello";
System.out.println(s3 == s4);
System.out.println(s3.equals(s4));
System.out.println(s5== s6);
System.out.println(s5.equals(s6));
打印机的结果是
false
true
true
true
s3和s4分别使用了new关键词来创建String类型的对象,系统会在堆内存中分配两块不同的空间地址来分别存放monkey,s3和s4分别指向这两块不同的地址,所以s3s4的结果是false。
String类中已经重写了equals方法,所以s3.equals(s4)的结果是true
因为s5和s6指向的是同一块常量池中hello所在的内存地址,所以s5s6的结果是true。
String类中已经重写了equals方法,所以s5.equals(s6)的结果也是true

开发中建议使用String s = “monkey1024”;这种方式创建字符串对象,可以减少堆内存的使用。
注意:比较两个字符串是否一致最好使用equals方法
String中的intern方法
在String类中有一个intern方法,当这个方法被调用的时候,如果在字符串常量池中存在与当前String相同的字符串时(equals),就会将该字符串返回,如果不存在时,就会将该字符串字面量放到字符串常量池中并返回该字符串的引用。
//下面代码可能在不同的jdk版本中执行的结果不一样
String s1 = new String("hello");
//false,一个指向堆内存中,一个指向字符串常量池
System.out.println(s1.intern() == s1);
//true,都指向字符串常量池
String s2 = "hello";
System.out.println(s2.intern() == s2);
练习
下面代码创建了几个对象?
String s1 = new String("www.monkey1024.com");
String s2 = new String("www.monkey1024.com");
答案
一共创建了三个对象,常量池中一个,堆内存上面有两个
使用String时需要注意的问题
在工作中尽量不要做字符串频繁的拼接操作。因为字符串一旦创建不可改变,如果频繁拼接,就会在字符串常量池中创建大量的字符串对象,给垃圾回收带来问题。
如果需要做字符串频繁的拼接操作,最好使用StringBuffer或者StringBuilder,这两个类在后面会讲到。
String s1 = "";
for(int i=0; i<100; i++){
s1 += i;//避免频繁的字符串拼接操作
}
System.out.println(s1);
String s2 = "a";
String s3 = "b";
String s4 = s2 + s3;
String s5 = "ab";
System.out.println(s5 == s4);
上面程序最后打印的结果是false,因为在做字符串拼接时会在堆内存中创建新的对象。
String类常用方法
char charAt(int index);获取index位置的字符
boolean contains(CharSequence s);判断字符串中是否包含某个字符串
boolean endsWith(String endStr);判断是否是以某个字符串结尾
boolean equalsIgnoreCase(String anotherString);忽略大小写比较两个字符串是否相等
byte[] getBytes();转换成byte数组
int indexOf(String str);取得指定字符在字符串的位置
int indexOf(String str, int fromIndex);从指定的下标开始取得指定字符在字符串的位置
int lastIndexOf(String str);从后面开始取得指定字符在字符串最后出现的的位置
int lastIndexOf(String str, int fromIndex);从后面开始指定的下标开始取得指定字符在字符串的位置
int length();获取字符串的长度
String replaceAll(String s1,String s2);替换字符串中的内容
String[] split(String s);根据指定的表达式拆分字符串
boolean startsWith(String s);判断是否是以某个字符串开始
String substring(int begin);根据传入的索引位置截子串
String substring(int beginIndex, int endIndex);根据传入的起始和结束位置截子串
char[] toCharArray();将字符串转换为char数组
void toUpperCase();转换为大写
void toLowerCase();转换为小写
String trim();去除首尾空格
String valueOf(Object obj);将其他类型转换为字符串类型
package com.monkey1024.string;
public class StringTest02 {
public static void main(String[] args) {
String s1 = "monkey1024";
// char charAt(int index);获取index位置的字符
System.out.println(s1.charAt(5));
// boolean contains(CharSequence s);判断字符串中是否包含某个字符串
System.out.println(s1.contains("key"));
// boolean endsWith(String endStr);判断是否是以某个字符串结尾
System.out.println(s1.endsWith("1028"));
// boolean equalsIgnoreCase(String anotherString);忽略大小写比较两个字符串是否相等
System.out.println(s1.equalsIgnoreCase("Monkey1024"));
// byte[] getBytes();转换成byte数组
String s2 = "abc";
byte[] b1 = s2.getBytes();
for(int i=0; i<b1.length; i++){
System.out.print(b1[i] + " ");
}
System.out.println();
// int indexOf(String str);取得指定字符在字符串的位置
System.out.println(s1.indexOf("y"));
// int indexOf(String str, int fromIndex);从指定的下标开始取得指定字符在字符串的位置
String s3 = "monkey1024monkeyy";
System.out.println(s3.indexOf("y", 6));
// int lastIndexOf(String str);从后面开始取得指定字符在字符串最后出现的的位置
System.out.println(s3.lastIndexOf("y"));
// int lastIndexOf(String str, int fromIndex);从后面开始指定的下标开始取得指定字符在字符串的位置
System.out.println(s3.lastIndexOf("y", 14));
// int length();获取字符串的长度
System.out.println(s3.length());
// String replaceAll(String s1,String s2);替换字符串中的内容
String s4 = "monkeymonkey1024monkey";
System.out.println(s4.replaceAll("key", "YYY"));
// String[] split(String s);根据指定的表达式拆分字符串
String s5 = "a,b,c,d";
String[] array1 = s5.split(",");
for(int i=0; i<array1.length; i++){
System.out.print(array1[i] + " ");
}
System.out.println();
// boolean startsWith(String s);判断是否是以某个字符串开始
System.out.println(s3.startsWith("m1"));
// String substring(int begin);根据传入的索引位置截子串
System.out.println(s3.substring(5));
// String substring(int beginIndex, int endIndex);根据传入的起始和结束位置截子串
System.out.println(s3.substring(6, 10));
// char[] toCharArray();将字符串转换为char数组
char[] array2 = s5.toCharArray();
for(int i=0; i<array2.length; i++){
System.out.print(array2[i] + " ");
}
System.out.println();
// void toUpperCase();转换为大写
System.out.println(s5.toUpperCase());
// void toLowerCase();转换为小写
System.out.println(s5.toLowerCase());
// String trim();去除首尾空格
String s6 = " java good ok ";
System.out.println(s6.trim());
// String valueOf(Object obj);将其他类型转换为字符串类型
Object o = new Object();
o = null;
System.out.println(String.valueOf(o));//建议使用这种方法转换字符串
//System.out.println(o.toString());//报出空指针错误
}
}
1-18String类简介的更多相关文章
- ImageView类简介
4.8 图片控件 本节将要介绍的是图片控件ImageView,首先对ImageView类进行简单介绍,然后通过一个案例来说明ImageView的用法. 4.8.1 ImageView类简介 Ima ...
- Spring Security——核心类简介——获得登录用户的相关信息
核心类简介 目录 1.1 Authentication 1.2 SecurityContextHolder 1.3 AuthenticationManager和Authenti ...
- DriverManager 驱动管理器类简介 JDBC简介(三)
驱动程序管理器是负责管理驱动程序的,驱动注册以后,会保存在DriverManager中的已注册列表中 后续的处理就可以对这个列表进行操作 简言之,驱动管理器,就是字面含义,主要负责就是管理 驱动 概述 ...
- Java基础-日期格式化DateFormat类简介
Java基础-日期格式化DateFormat类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.DateFormat类概述 DateFormat 是日期/时间格式化子类的抽象 ...
- Java基础-StringBuffer类与StringBuilder类简介
Java基础-StringBuffer类与StringBuilder类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringBuffer类 在学习过String类之后 ...
- 34、Collections工具类简介
Collections工具类简介 就像数组中的Arrays工具类一样,在集合里面也有跟Arrays类似的工具类Collections package com.sutaoyu.Collections; ...
- JAVA nio 2 和 Path 类简介
想要初步了解 NIO.2 API,也就是通常所说的“JSR203: More New I/O APIs for the Java Platform”,最好的切入点就是新的抽象类 java.nio.fi ...
- QT中QWidget类简介
一.详细描述 QWidget类是所有用户界面对象的基类.通俗的来讲,Qt基本上所有的UI类都是由QWidget继承出来的,而QWidget继承于QObject, 大家可以查阅Qt source 即可 ...
- Java并发包中CopyOnWrite容器相关类简介
简介: 本文是主要介绍,并发容器CopyOnWriteArrayList和CopyOnWriteArraySet(不含重复元素的并发容器)的基本原理和使用示例. 欢迎探讨,如有错误敬请指正 如需转载, ...
- osg探究补充:DatabasePager类简介
简介 DatabasePager类,也就是常说的数据库分页技术,简单来说,就是在进行数据库查找时,有可能满足条件的数据很多,为了提高相应速度我们进行数据查找时进行分页查找与显示,当点击下一页时才会进行 ...
随机推荐
- (转载)解决MySql 数据库 提示:1045 access denied for user 'root'@'localhost' using password yes
今天想用用MySQL 数据库 谁知道老提示 1045 access denied for user 'root'@'localhost' using password yes 最后在csdn 上找到 ...
- BootStrap-DualListBox怎样改造成为双树
BootStrap-DualListBox能够实现将所选择的列表项显示到右边,未选的列表项显示到左边. 但是左右两边的下拉框中都是单级列表.如果要实现将两边都是树(缩进树),选择某个节点时,其子节点也 ...
- js与原生的交互
一.与安卓的交互 Android与js通过WebView互相调用方法,实际上是: Android去调用JS的代码 JS去调用Android的代码 二者沟通的桥梁是WebView 对于android调用 ...
- 有关定时器setTimeout()、setInterval()详解
JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成. setTimeout() setTimeout函数用 ...
- Android ViewDragHelper及移动处理总结
概述 2013年谷歌i/o大会上介绍了两个新的layout: SlidingPaneLayout和DrawerLayout,现在这俩个类被广泛的运用.我们知道在我们实际的开发中往往会涉及到很多的拖动效 ...
- 一步一步学Silverlight 2系列(24):与浏览器交互相关辅助方法
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- Netty代码分析
转自:http://www.blogjava.net/BucketLi/archive/2010/12/28/332462.html Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开 ...
- 书写优雅的shell脚本(三) - shell中exec解析
参考:<linux命令.编辑器与shell编程> <unix环境高级编程> exec和source都属于bash内部命令(builtins commands),在bash下输入 ...
- Python-Django使用MemcachedCache缓存
最近工作中使用到缓存,简单记录之... 关于django的几种缓存方式,就不在做介绍了,网上一搜一大把:1.8.2官方文档, Django 缓存,Python菜鸟之路:django缓存 学习了之后,选 ...
- 148D
概率dp+记忆化搜索 dp[i][j][0]表示当前公主走公主赢的概率,dp[i][j][1]表示当前龙走公主赢的概率,然后剩下的就是一些细节的讨论,记忆化搜索很方便 #include<bits ...