我要提问的问题如下:
下面这个类一共创建了几个对象,它们分别在什么的方?
public class Test {
public static void main(String[] args) {
String s1=new String("abc");
String s2="abc";
String s3=new String("abc");
System.out.println(s1==s2);
System.out.println(s1==s3);
}
}
下面这个类一共创建了几个对象,它们分别在什么的方?
public class Test {
public static void main(String[] args) {
String s1=new String("abc");
String s2="abc";
String s3=new String("abc");
System.out.println(s1==s2);
System.out.println(s1==s3);
}
}
变量名其实类似与c++里面的pointer,<think in java>中把这个叫做reference,你用==其实相当于比较pointer
String s1=new String( "abc ");
String s2= "abc ";
没有差别System.out.println(s1==s2);
要写s1.euqals("s2")吧
s1==s2判断的好像是地址
1)三个引用。
2)s1引用的String对象的空间在堆中。s2引用的String对象在常量区中。其实就是一个字符序列。s3引用的String对象的空间在堆中。
给引用。两个创建String对象的语句都是返回一个String对象的引用,
但是在jvm对两者的处理方式是不一样的。对于第一种,jvm马上在堆中,创建一个String对象,然后将该对象的引用返回给用户。对于第二种,jvm首先会在内部维护的字符串池(String pool)中通过String的equals方法查找是
对象池中是否存放有该String对象,如果有,返回已有的String对象给用户,而不会在堆中
重新创建一个新的String对象;否则,jvm会创建新的String对象,将其返回给用户,同是将
该引用添加到字符串池中。
使用new创建对象是,jvm是不会主动把该对象放到字符串池里面的,除非程序调用String的intern方法。
String s1=new String( "abc "); 2个 堆1,字符串常量池1
String s2= "abc "; 1个 池1
String s3=new String( "abc "); 2个 堆1,字符串常量池1
System.out.println(s1==s2); false 比较地址s1在堆s2在池
System.out.println(s1==s3); false 在堆中的2片不同地方
3个引用和2个对象,String s2 = "abc";是在常量池中创建的,如果之前没有的话。这个是在编译期间产生的,存在于.class文件中。使用new产生的对象"abc"在堆内存中,是运行时产生的,同时也会到常量池去检查一下有没有"abc"存在在该例中常量池中在编译期就有了"abc"了,所以总共就是两个对象。
脱离该例子.字符常量也是一个对象.所幸的是JAVA处理String常量的方式与其他语言的处理普通字符串的方式相同.
只有包含变量的String表达式需要显示的调用intern()进行扣留。什么是字符串扣留,每本java基础书上都有讲到吧?
public static void main(String[] args) {
String s1=new String( "abc ");//此处"abc"和 new String( "abc ")生成2个对象
String s2= "abc "; //此处因为扣留机制,没有生成对象(*)
String s3=new String( "abc ");//new String( "abc ")生成一个对象
System.out.println(s1==s2);
System.out.println(s1==s3);
}
}一共三个,所以你会打印出2个false;
应该说在String s2= "abc "; 这里,实现扣留机制应该先生成一个对象,然后又扣留将其销毁掉。
可以这么说,是生成了4个对象,但销毁了1个。
其实稍微想想,虚拟机应该不会这么烂(做生成再销毁的事情)。我比较支持3个的说法。
问一下,如何去常量池中检查?是用equals()方法么?
如果是的话,用equals()方法应该是这样用吧:
XXX.equals("abc"); --其中的XXX是什么?
没有严格把引用和对象区分开来看,把引用和对象混为一谈,
导致很多人不能正确理解引用和对象。。
问题一:我声明了什么! String s = "Hello world!"; 许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。
这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句: String string = s; 我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。