String面试题

String面试题。

1.String的基本特性。

不变性:是一个不变模式的对象,不变模式的主要作用是当一个对象需要被多线程共享并频繁访问时,可以保证数据当一致性。 
常量池优化:String对象创建之后,会在字符串常量池中进行缓存,下次创建同样当对象时,会直接返回缓存当引用。
final:String类不可被继承,提高了系统当安全性。

2.String类型为何设计为不可变。

因为在程序编写的过程中,会大量地用到String常量,如果每次声明一个String引用都要新建一个String对象,那么会造成空间的极大浪费。
于是,可以在java的堆中开辟了一块存储空间String pool,用于存储String常量对象。当有多个String引用指向同样的String字符串时,实际上是指向的是同一个Sting pool中的对象,而不需要额外的创建对象,可以节省空间。
但是使用常量池必须保证String对象是不可变的。

3.String类型设计为不可变的好处。

1.多线程并发访问共享变量,可以保证线程安全。
2.可以使用字符串常量池,节省程序运行空间。
3.String的不可变保证了hash值的不可变,在使用hashCode的地方可以保证hash值的不变。例如以String作为hashMap的key。

4.Java如何实现不能被继承。

1.使用final关键字。
2.使用私有构造器。

5.String不是基本数据类型。

6.String的实例化方法。

public class Demo {

    public static void main(String[] args) {
        /**
         * 使用直接赋值的方式进行创建。
         * 对象创建在常量池中
         * ==比较的是堆中的引用地址。
         */
        String str1 = "hello word";
        String str2 = "hello word";
        //验证str1和str2指向的对象是否为同一个?
        System.out.println(str1 == str2);
        //输出结果为true,验证了对象是同一个对象。

        /**
         * 使用构造器创建对象。
         * 对象创建在堆中。
         */
        String str3 = new String("hello word");
        String str4 = new String("hello word");
        //验证str3和str4指向的对象是否为同一个?
        System.out.println(str3 == str4);
        //输出结果为false,验证了不是同一个对象。

        //验证两种不同的创建方式,对象地址是否相同
        System.out.println(str1 == str3);
        //输出结果为false,验证了不是同一个对象。
            
        char[] chars = {'您','好'};
        String str5 = new String(chars);   
    }
}
7.==和equals的区别。
==
	用于比较基本类型时,比较的是值是否一样。
	用于比较非基本类型时,比较的是对象的地址引用是否相同。
euqals
	只能用于比较非基本类型,属于Object中的方法。
	默认比较引用地址是否相同,具体看子类重写equals的逻辑。

JDK1.8中String类的equals的重写逻辑。

public boolean equals(Object anObject) {
		//比较是否为同一个对象。
        if (this == anObject) {
            return true;
        }
        //如果传入的对象是String类型的
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            //判断字符数组长度是否相同
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                	//循环判断数组中的每个值是否相同。
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

8.JDK1.9对String对象做的优化。

参考链接

9.String的intern方法。

//本地方法
public native String intern();

当调用某个对象当intern方法时,会去字符串常量池中寻找,如果找到一个值相等当字符串对象,则直接返回该对象当引用,如果不存在,则在字符串常量池中创建该对象,并返回对象当引用。

10.经典面试题。

基本原则(以常量池中不存在为前提)。

//在常量池中创建一个。
String str1 = "abc";
//常量池中一个,堆中一个.new关键字必定会在堆中创建一个对象。
String str2 = "def";
//创建一个,字面常量进行相加会优化
String str3 = "a"+"b";
//字面常量和new对象进行相加,会在堆中创建一个StringBulider对象,且不会将StringBuilder对象放入常量池。
String str4 = "a"+ new String("b");

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

public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * javap -verbose 指令查看汇编。
         * 如果常量池中不存在abc对象,则创建两个,常量池中一个,堆中一个。
         * 如果常量池中存在则在堆中创建一个。
         */
        String str1 = new String("abc"); 
}

2.创建了几个对象?

 public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * 常量池中如果不存在ab 则在常量池中创建了一个。
         * 存在,则没有创建对象。
		 * 虚拟机看到两个或者多个字面量进行相加时,会对其进行优化,在常量池中只创建一个对象。
         */
        String str1 = "a" + "b";
    }

3.创建了几个对象?

public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * 四个
         * 常量池中为(a,b)
         * 堆中为(b,StringBuilder)
         *
         *
         */
        String str1 = "a" + new String("b");
}

4.创建了几个对象?

public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * 创建了三个。
         * 堆中 str1 str2.
         * 常量池中 abc 一个。
         */
        String str1 = new String("abc");
        String str2 = new String("abc");

}

5.创建了几个对象?

 public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * 创建了四个。
         * 常量池1个 a
         * 堆中两个String a、a.
         * 堆中一个StringBuilder。
         *
         */
        String str1 = new String("a")+new String("a");
}

6.创建了几个对象?

public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * 五个
         * 常量池 a、b 
         * 堆中 String对象  a、b
         * 堆中 StringBuider对象  ab
         */
        String str1 = new String("a")+new String("b");
}

7.创建了几个对象?

public static void main(String[] args) {
        /**
         * 此代码创建了几个对象?
         * 五个
         * “”空字符串也会创建对象。
         * 存在方式同上。
         */
        String str1 = new String("a")+new String("");
}

8.判断输出结果。

public static void main(String[] args) {
        String str1 = "abcd";
        String str2 = "ab"+"cd";
        //输出结果为true
        System.out.println(str1 == str2);
}

9.判断输出结果。

public static void main(String[] args) {
        String str1 = "abcd";
        String str2 = "ab";
        String str3 = "cd";
        //此处在堆中进行操作,相加使用的是StringBuilder的append()方法。
        String str4 = str2 + str3;
        //输出结果为false.
        System.out.println(str1 == str4);
}

10.判断输出结果。

public static void main(String[] args) {
        String str1 = "Hello World";
        String str2 = "Hello " + "World";
        /**
        * 输出结果为true。
        */
        System.out.println(str1 == str2);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值