初识String类


在Java程序中,所有的字符串都要求使用“””(双引号)进行定义,同时也可以利用“+”实现字符串的连接处理。

一、String类简介

字符串严格意义上来讲并不能算是一个基本数据类型,在Java中,为了方便开发者进行项目的编写,所以利用JVM的支持,制造了一种可以简单使用的String类,可以向基本数据类型一样可以进行直接赋值处理。
String这个类里面之所以能保存字符串主要的原因是其定义了一个数组,也就是字符串中的每一个字符都是保存在了数组之中,从JDK1.9开始String类之中的数组类型采用了byte类型。所谓的字符串就是对数组的一种特殊包装,既然包装的是数组,那字符串中的内容肯定是无法改变的。

JDK1.8以前的String支持类JDK1.9及以后的String支持类
String保存的是字符数组String保存的是字节数组
private final char value[];private final byte[] value;

在String类里面除了可以使用直接赋值的形式为对象进行实例化之外,也可以按照传统方式利用构造函数进行对象的实例化处理。

二、字符串比较

1、面试与笔试题:请解释String比较中双等号与equals()区别?
 双等号 “==”:进行的数值比较,如果用于对象比较上比较的是两个内存的地址数值;
 equals():是类所提供的一个比较方法,可以直接进行字符串内容的比较。

2、如果要判断两个int型变量是否相等,那么肯定使用“==”来完成,这个是由程序直接提供相等运算符。
实例:使用双等号判断:

public class StringDemo{
	public static void main(String args[]){
		int x=0;
		int y=2;
		System.out.printIn(x==y); //结果:false
	}
}

String类相等的判断可以使用“==”,只不过判断的不准确而已,因为它判断的是存放地址,下面例子为例。

public class StringDemo{
	public static void main(String args[]){
		String strA="www";
		String strB=new String("www");
		System.out.printIn(strA==strB); // 结果:false
	}
}

程序分析:虽然两个字符串的内容是相同的,但是“==”也无法得到准确的相等判断,如果要实现字符串准确的相等判断那么应使用String类中提供的一个比较方法equals。
 字符串比较:public boolean equals(String str);
范例:利用equals()实现字符串比较。

public class StringDemo{
	public static void main(String args[]){
		String strA="www";
		String strB=new String("www");
		System.out.printIn(strA.equals(strB)); // 结果:true
	}
}

三、String类的匿名对象

在java程序中,任何一个整数都是int型的,任意一个小数默认是double类型的,对于字符串而言,首先程序之中不会提供有字符串这样的基本数据类型,那么可以提供的只是String类,所以任何使用“"”(双引号)定义的字符串常量实际上描述的都是一个String类的匿名对象。
赋值时的内存关系如下图:
在这里插入图片描述
证明匿名对象的存在

public class StringDemo{
	public static void main(String args[]){
		String strA="www";
		System.out.printIn(="www".equals(strA)); // 结果:true
	}
}

此时可以发现字符串变量可以明确的调用equals()方法实现对象相等的判断,可以得出结论,程序中没有String类型常量这种基本类型,有的只是String类的匿名对象。

关于对象相等判断的小技巧(实际商业项目的开发中常用):
在以后进行项目开发的时候,如果现在某些数据是由用户输入,并且要求这些数据为一个制定内容的情况下建议将字符串常量写在前面,记住是前面,写前面可以避免空指针异常,如果在后面后出现空指针异常。实例如下:
正常:将字符串常量写在前面

public class StringDemo{
	public static void main(String args[]){
		Scanner scanner = new Scanner(System.in);
		String input= scanner.nextInt(); // 请输入一个数据
		System.out.printIn(="www".equals(input)); // 结果:true或者false
	}
}

空指针异常:将字符串常量写在后面

public class StringDemo{
	public static void main(String args[]){
		Scanner scanner = new Scanner(System.in);
		String input= scanner.nextInt(); // 请输入一个数据
		System.out.printIn(=input.equals(“www”)); // 结果:可能出现空指针异常
	}
}

四、String类对象两种实例化方式比较

String本身包装的就是一个数组,并且其有两种对象的实例化形式:直接赋值、构造函数。

1、 分析直接赋值的对象实例化模式

在程序之中只需要将一个字符串赋值给String类的对象就可以实现对象的实例化处理。

	public class StringDemo{
	public static void main(String args[]){
		String strA="www";
		String strB="www";
		System.out.printIn(strA == strB); //进行地址判断,结果:true
		}
}

程序分析:此时程序的结果返回了“true”,那么可以知道这两个对象所指向的堆内存地址相同,也就是这两个对象指向了同一个堆内存空间。其内存空间分析如下:
在这里插入图片描述
String类型的堆内存空间可以共享,主要的原因是因为Java的底层提供有一个专门的字符串池(字符串池的本质就是字符串数组)。
在这里插入图片描述

2、 分析构造方法实例化

String类型的构造方法:public String(String str);
实例:

public class StringDemo{
	public static void main(String args[]){
		String strA=new String("www");
		System.out.printIn(strA); 
	}
}

程序分析:此时会开辟两块堆内存空间,而后只会使用一块,而另外一个由于字符串常量所定义的匿名对象将成为我们的垃圾空间。
程序内存空间分析:
在这里插入图片描述
构造方法与赋值方法实例:

public class StringDemo{
	public static void main(String args[]){
		String strA="www";
		String strA=new String("www");
		System.out.printIn(strA==strB);  // 执行结果:false
	}
}

程序分析:构造方法实例化对象实际上是属于一种自己专用的内存空间,但是在String类里面提供有帮助开发者实现手工入池的处理情况,这个方法:public String intern();
实例:手工入池

public class StringDemo{
	public static void main(String args[]){
		String strA="www";
		String strA=new String("www").intern();
		System.out.printIn(strA==strB);  // 执行结果:true
	}
}

总结:
 直接赋值的特点:可以自动将对象保存到对象池之中。
 构造方法赋值的特点:就是在堆内存中开辟新的内存空间,在构造方法实例化String类对象时不会自动出现保存到字符串池的处理。

面试题与笔试题:请解释String类两种对象实例化方式的区别?
直接赋值:只会产生一个实例化对象,并且可以自动保存到对象池之中,以实现该字符串实例的重用。
构造方法:构造方法会产生两个实例化对象,并且不会自动入池,无法实现对象重用,但是可以利用intern()方法手工入池处理。
以后String类型赋值直接使用“=”进行赋值。

五、String对象池

对象池也叫常量池。
对象池的主要目的是实现数据的共享处理。
以String对象池为例,里面的内容就是为了重用,重用就是共享设计,在Java中,对象池(常量池)可以分为两种:
 静态常量池:指的是程序(.class)在加载的时候会自动将此程序之中保存的字符串、普通的常量、类和方法的信息等等,全部进行分配。
 运行时量池:一个程序(.class)加载之后,里面可能有些我们的变量,这个时候提供的常量池叫运行时常量。
实例:静态常量池

public class StringDemo{
	public static void main(String args[]){
		String strA = "wwwW";
		String strB = "ww"+"wW";
		System.out.printIn(strA==strB); //执行结果:true
	}
}

程序分析:本程序给出的内容全部都是常量数据(字符串中的常量都是匿名对象),所以最终在程序加载的时候会自动帮助开发者处理好相应的连接。
内存空间分析如下:
在这里插入图片描述
实例:运行时常量池

public class StringDemo{
	public static void main(String args[]){
		String info = "en";
		String strA = "wwwWen";
		String strB = "ww"+"wW"+info;
		System.out.printIn(strA==strB); //执行结果:false
	}
}

程序分析:这个执行结果之所以为一个false,是因为程序在加载的时候并不确定info是什么内容,因为在进行字符串连接的时候info采用的是一个变量,而变量的内容可以修改,所以最终strB的结果就不是所需要的真实的结果。
内存分析:
在这里插入图片描述

六、字符串的内容不可修改

在String类之中包含的是一个数组,数组最大的缺点在于长度不可改变,当设置了字符串之后,会自动进行数组空间的开辟,开辟的内容长度是固定的。
内存分析:
在这里插入图片描述
修改的不是字符串的内容,而是开辟了新的堆内存空间,每次就指向了新的内存空间,之前前的内存空间就变成类垃圾,有GC回收。

七、Java中的主方法

Java中的主方法:public static void main(String args[])
 public:访问权限,主方法时一切的开始点,开始点一定是公共的。
 static:此方法可由类直接完成。
 void:主方法是一切的起点,起点一旦开始就没有返回的可能。
 main:是一个系统定义好的方法名称。
 string[] args:字符串数组,可以实现程序启动参数的接受。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值