String s1="hello";
         String s2="hello";
         String s3=new String("hello");
         String s4=new String("hello");
         if(s1==s2)
         System.out.println(s1==s2);//输出了true。。。
         System.out.println(s1==s3);//输出了false
 
        System.out.println(s3==s4);//输出了false
        System.out.println(s1=="hello");//输出了true
         System.out.println(s3=="hello");//输出了flase
         System.out.println("hello"=="hello");//输出了true        Scanner in=new Scanner(System.in);
         String s5;
         s5=in.next();//输入hello
         System.out.println(s1==s5);//false
         System.out.println(s3==s5);//false

在学习String类型的时候,我们知道String类型有两种创建方式,一个是,String s=“string”,一个是String s=new String(“string”)

这两个看起来是一样的,实际上却存在本质的区别;

我们知道在java中的内存有栈内存和堆内存。栈内存中存放变量名这些东西,存放的是对对象的引用,而堆内存中存放的是实际的对象。同时除了这两个以外,java中还有一个叫做常量池的东西。一些常量,将会放在这里面。

在java中,为了程序执行的效率。要是使用String=“string”这个创建String对象的方式,这个对象将会创建在常量池里面,对于String类型来说叫做串池。而这个对象的引用则是在栈内存中,要是我们再用双引号创建一个String类型,将会先在串池里面寻找是不是有这个对象,如果有,这个引用就指向这个对象,要是没有,就再在串池里面新建一个字符串对象。

而如果使用new创建对象,或者通过输入来创建对象,创建的对象都会在堆内存中,也就是说,他的引用指向的是堆里面的一个内存快。

而“ ==” 对于引用类型来说,判断的是指针是否相同,对于两个直接用双引号创建的字符串,他在串池中,他的两个引用都指向他,所以两个字符串变量是相等的(字符串变量就是一个指针,他们的值相等),而我们用的字面值,也是存放在串池中的,他的地址很明显就是字符串变量(指针)所指向的地址,所以是相等的,也就是true

而new出来的对象,他的地址是不共享的,也就是两个对象的存储地址不同,自然就是不同的指针。


我们要知道的是,String s;//s是一个指针变量,他的值是一个内存地址,而这样的方式我们称为指针,要从内存的角度去理解


参考资料:

java堆,栈和常量池

http://www.iteye.com/topic/634530

java String两种赋值方式的比较

http://blog.163.com/woshihezhonghua@126/blog/static/1271436362012101214031911/

java里用“==”比较两个字符串的问题

http://zhidao.baidu.com/link?url=JU17Pwt70JUdvQjns4EBZ1PswGAogtpWgjKnxb--qY3y73svViQn4zGBG3JDEl88k99rP-agYjRUGKr--50HIa