JAVA面试笔试题之字符串篇【亲手实践】

package ai;

public class DemoString {
	//类变量
	final static String name = "zhangSanFeng";
	final static String firstName = "zhang";
	final static String lastName = "SanFeng";
	/**
	 * static:何为静态,goal变量(引用)存放在方法区中(方法区是常量池的一部分)
	 * 对于静态的东西,JVM在加载类时,就在內存中开辟了这些静态变量的空间(内存空间),
	 * 即编译时就为这些成员变量的实例分配了空间
	 * 而“ab”存在引用goal指向的堆内存中
	 */
	private static String goal = new String("ab");  
	public static void main(String[] args) {
		//字符串比较 以及引用类型变量比较
		//strTest1();
        //secondTest();
        //finalTestDemo();
		checkIt();
	}

	private static void checkIt() {
		String s1 = "a";   
        String s2 = "b";   
        String s = s1 + s2;   
        System.out.println(s == goal); //false  s的位置是常量池,goal位于方法区  
        System.out.println(s.intern() == goal);   
        System.out.println(s.intern() == goal.intern());
	}

	/**
	 * final修饰变量   
		1、修饰的变量必须是基本数据类型:告知编译器这一块数据是不变的,这样可以在执行计算时,减少一些运行时的负担。
		2、无论什么情况,final修饰的变量必须初始化。
	 */
	private static void finalTestDemo() {
		//System.out.println(name == (firstName + lastName));
		byte  a = 1;  
		byte  b = 3;  
		//byte  c = a + b;      //直接加会出错,因为运算时Java虚拟机进行了转换,导致把一个int赋值给byte  
		//-----------------------------------------------------------------------------------  
		final  byte  num1 = 1;   
		final  byte  num2 = 3;  
		byte num = num1 + num2;     //加上final就不会出错。
		//System.out.println(num);//一个问题:byte如何转int?
		//=========================================================================================================
		final String f1 = "abc";
		final String f2 = "ab";
		final String f3 = "c";
		//final s = null;
		/**
		 * 该处花了很多时间来搜索、理解,final修饰的变量,编译器会把它当做编译期常量使用?【答案:Final变量 编译时期就确定具体值】
		 */
		System.out.println(f1 == (f2+f3));//该处等同于【f1=="ab"+"c"】
		
	}

	private static void strTest1() {
		/**
		 *  你或许听说过“字符串常量池”这个概念,究竟什么是字符串常量池?有人说是一个字符串对象容器。答案很接近了,但是不完全正确。
			事实上他是一用来保存字符串对象引用的容器。
			即使字符串是不可变的,它仍然和Java中的其他对象一样。对象都是创建在堆中,字符串也不例外。
			所以字符串常量池仍然依靠堆,他们存储的只是堆中字符串的引用。
		 */
		String s1 = "abc";//在字符串常量池中开辟一段内存空间
		String s2 = new String("abc");//在堆中开辟一段内存空间
		String s3 = new String("abc");//在堆中开辟一段内存空间
		System.out.println(s1 == s2);//false
		System.out.println(s2 == s3);//false
		System.out.println(s2 == s3);//false
		System.out.println("-----------------");
		System.out.println(s1.equals(s3));
		System.out.println(s1.equals(s2));
		System.out.println(s3.equals(s2));
		System.out.println("-----------------");
		String start = "Hello";
        String end = start.concat(" World!");
        System.out.println(end+"|"+start);
        
        String one = "someString";
        String two = "someString";
        System.out.println("-----------字符串常量池------");
        System.out.println(one.equals(two));
        System.out.println(one == two);
        //在这个例子中,实在没有必要为一个相同的字符串对象创建两个实例。如果字符串像StringBuffer一样是可变的,
        //那么我们会被迫创建两个对象(如果不这样做的话,通过一个引用改变它的值,将会导致其他引用的值也同样改变,从而可能发生错误)。
        //但是,我们知道字符串对象是不能被改变的,我们可以安全地通过两个引用one和two来使用一个字符串对象。
        System.out.println("----test StringBuffer----");
        StringBuffer sb1 = new StringBuffer("123");
        StringBuffer sb2 = new StringBuffer("123");
        System.out.println(sb1 == sb2);
        System.out.println(sb1.equals(sb2));
        
        System.out.println("-------test Object对象测试-----");
        Tickets t1 = new Tickets();
        Tickets t2 = new Tickets();
        System.out.println(t1 == t2);
        System.out.println(t1.equals(t2));
	}

	private static String a = new String("ab");   //堆内存(地址 )
	private static void secondTest() {
		String s1 = "a";   
        String s2 = "b";   
        String s = s1 + s2;   
        System.out.println(s == a); //地址不同,一个位于   静常,另一个位于运常,故false
        
        //对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
        System.out.println(s.intern() == a);   
        System.out.println(s.intern() == a.intern());   //true 
        System.out.println(s.equals(a));    //true
        System.out.println("==========");
        Test2 t1 = new Test2();
        Test2 test2 = new Test2();
        System.out.println(t1.equals(test2));
        System.out.println("================================");
        String hello = "hello";   
        String hel = "hel";   
        String lo = "lo";   
        //false 该题我做错了,因为没有认识到:对于那些在编译时就能确定的字面量都会存放在运行时常量池中。正确答案是:true
        System.out.println(hello == "hel" + "lo");   
        System.out.println(hello == "hel" + lo);   //false【其中lo是变量,在编译时不能确定值】
	}
}

附上几张图,方便大伙理解。以上是个人笔记,不喜勿喷。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值