飞道的博客

Java基础面试题

338人阅读  评论(0)

Java基础

前言

最近,感觉压力比较大,所以挑战下基础面试题,加深下自己对基础知识的理解。Java基础知识实在是太多了,这里打算持续更新,总结下常见的面试题。

1 下面的代码创建了几个对象

String str = new String("Hello");

以上代码,实际上创建了2个对象,JVM首先会在对象池中创建一个对象,然后根据对象池中的对象,在堆中创建一个对象。

String str1 = new String("Hello");
String str2 = new String("Hello");

这段代码,实际上创建了3个对象,JVM首先会在对象池中创建一个对象,而对象池中的对象,都是被共享的,所以str1和str2在对象池中,其实是同一个对象。通过new的方式,在堆中,又创建了对象str1,对象str2,str1和str2这两个引用,属于不同的内存地址,堆中创建了2个对象,综上所述,以上代码片创建了3个对象。

2 String对象是如何保证其对象的内容不可改变

这个问题在基础中,也算是很常见的了,这里做一下总结。

看本例子之前,给伙伴们脑补下基础知识:==基本数据类型中,比较的值是否相等,在引用数据类型中,比较的是内存地址是否相等(也即是执行的是不是同一个对象)。而equals比较的内容是否相等

private static void test8() {
		String str1 = new String("hello");
		String str2 = new String("hello");
		String str3 = str1;

		// str1和str2都使用new创建了对象,所以JVM会在堆中会创建两个不同的对象,所以属于不同的内存空间,str1和str2指向堆中的是,两个不同的内存地址,所以结果为false
		System.out.println("str1 == str2:" + (str1 == str2));// false
		// 这个输出语句str1.equals(str2)是调用了String类中的equals方法,该方法用于比较两个字符串对象的内容是否相等,结果为true。
		System.out.println("str1.equals(str2):" + str1.equals(str2));// true

		// 将str1赋值给了str3,指的是将str1对象的引用,赋值给了str3,这时候str1和str3,内存地址相同,指向堆中的同一块内存,所以这里返回true
		System.out.println("str1 == str3:" + (str1 == str3));// true
		// str1和str3指向堆中的同一块内存,所以值的内容相等,结果是true
		System.out.println("str1.equals(str3):" + str1.equals(str3));// true

		// 重点来了,String对象的不可变特性,这里修改了str1的内容
		str1 = "world";

		// 对于上面的 String str3 = str1
		// 这一行代码,小伙伴们会不会有这样的疑问,既然str1和str3具有相同的内存地址,引用的是堆中的同一个对象,为什么str1的值被改变了,str3的值并不会被改变呢?
		System.out.println("str1的值 = :" + str1);// str1的值 = :world
		System.out.println("str3的值 = :" + str3);// str3的值 = :hello

		// 这里修改了str1的内容,这就涉及到了Java中String对象的不可变性
		System.out.println("str1 == str3:" + (str1 == str3));// false
		// 这里内容已经不一样了,所以返回false
		System.out.println("str1.equals(str3):" + str1.equals(str3));// false
	}

该怎么理解Java中String对象的不可变性呢,简单来说就是:一旦一个String对象被创建并且被初始化(赋值)了,这个对象的值就不会再改变

一旦一个String对象在内存中创建,它将是不可改变的,所有的String类中方法并不是改变String对象自己,而是重新创建一个新的String对象。

也就是说str1 = “world”,并不是改变了原有对象的值,而是在对象池中,创建了一个新的字符串共享对象,这个对象的值是world,并把这个对象的引用赋值给了str1,而str3这个引用依然指向的是原来的那个对象,所以这时候str1和str3是两个不同的内存地址。

总结:
一个String对象在堆内存中创建以后,就不能被改变了。正因为String对象的不可变性,如果需要对字符串进行大量的修改、添加字符、删除字符等操作时,尽量不要使用String对象,因为这样会频繁的创建新的String对象,浪费大量的不必要的内存,也需要耗时来执行垃圾回收,从而导致程序的执行效率下降。

如果我们需要可改变的字符串,则需要使用字符串生成器StringBuffer或者StringBuilder。

注意:String对象的所有方法都不会改变其本身,而是会返回一个新的String对象

3 持续更新中。。。

创作不易,如果觉得这篇文章对你有帮助,点个赞呗

写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!

如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!

给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!


转载:https://blog.csdn.net/smilehappiness/article/details/105889524
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场