String b = new String("1"+"2")这句话在内存里会有几个对象呢有的人说是1个,就一个:new("12")
有的人说是四个,“1”,“2”,“12”,new("12")
还有人说是五个,“1”,“2”,“12”,new("12"),b答案到底是什么呢,小弟在线等权威解答!
有的人说是四个,“1”,“2”,“12”,new("12")
还有人说是五个,“1”,“2”,“12”,new("12"),b答案到底是什么呢,小弟在线等权威解答!
解决方案 »
- Image绘制图像的问题
- 各位大侠给个例子用java读取shp,shx格式的文件,在线急等!!!
- 并非非常完美 发现Java虚拟机内存泄露问题
- 怎么会事啊 这是
- 请问:java的窗口程序非要用JPanel,GridLayout,JLabel三个吗,能不能用别的呀,
- 怎么将用netbeans建立的项目转成.exe的可执行文件
- int i=0;i<a.length;i++
- 请大家提点关于用JAVA做毕设的好建议!
- java线程交互问题wait(),notifyAll()
- welcome to discuss about the JDO and Enitity Bean
- 求java大神支招
- LINUX socket服务器主动关闭的问题
如果说最终内存里的对象只有一个,因为("1"+"2")作为参数传递之后的匿名对象会自动销毁,最终只存在对象new("12")一个对象。b只是一个对象的引用,不算对象.
看样子应该是1,2,12 可是java编译的时候会不会和String b = new String("12")没啥区别呢
1个
StringBuilder 1个
"1" 1个
"2" 1个
组合起来,"12" 1个
new String("12") 1个
谢谢你,但我认为肯定得有new这个生成的对象啊!!
谢谢啦,怎么StringBuilder 1个 ,这是怎么回事呢?
"1" + "2",这种拼装字符串,JDK会使用StringBuilder.append来拼接字符串。
"1","2": 2个。
"1"+"2": 1个,
new : 1个
b=直接地址赋值不建立对象。验证程序:public class test {
public static void main(String[] args) {
String a = "1"; String b = "2"; String c = a + b; String d = new String(c); String e = d; System.out.println(a==b);
System.out.println(b==c);
System.out.println(a==c);
System.out.println(c==d);
System.out.println(d==e); }}
输出结果:
false
false
false
false
true
http://blog.csdn.net/fg2006/article/details/6713070
"1" + "2" == "12";测试不为true?
new是一个,"1" + "2"是一个(就是"12",在字符串池中),就两个对象;
区分下"1" + "2" 和 "1" + a(这里的a是变量)就清楚了;
首先被编译器优化为String b = new String("12"),注意是编译器,不会运行时!
然后"12"是一个常量,在类加载时进入常量池中,在运行时生成了一个对象
++我认为也是两个。。一个 "12" 一个new(12)
对于:String b = new String("1"+"2")
首先,我们平常创建对象的方式有两种,一个是利用new关键字,另外一个是利用反射机制的newInstance方法。以及String类型的直接“赋值”方法:例如 String str = “1”;
第二:我们把上面的代码分解为String b, =, new String(), 以及“1” + “2” 四个部分,很显然,String b只是声明了一个名为str的变量,没有创建对象;而 = 是对str进行初始化,把某个对象的引用赋值给str;这样要想要创建对象,就是在下面的两种方式中了。
第三:对于new String(),以及“1” + “2”,要考虑到字符串连接池的知识,在JVM中存在着由String类管理的字符串连接池,其中保存着很多的String对象,可以被共享使用,提高了效率,同时由于String类都是final类型的,不必担心对象共享带来的混乱。在new一个对象的时候,先去连接池查看是不是有了这么一个对象,没有的话才去创建这个对象。对于“1” + “2”,这种形式的常量连接,是在编译时就确定优化为“12”了,因此里面的“1” + “2”只是创建了一个对象。
第四:“1” + “2” 是创建了一个对象,那么new String();也创建了一个,因此总共是创建了两个!!
System.out.println("12" == "1" +"2");
结果:true
so..
对于java程序中的字符直接量,JVM会使用一个字串池来保存它们。当第一次使用某个字符串直接量时,JVM会将它放入字符串池中进行缓存。在一般情况下,字符串池中的字符串对象不会被垃圾回收。当程序再次需要使用该字符串时,无需重新创建一个新的字符串就可以直接让引用变量直接指向字符串中已有的字符串。而使用new操作创建的字符串对象不指向字符串池中的对象,但是可以使用intern方法使其指向字符串池中的对象对于java程序中的字符直接量,JVM会使用一个字串池来保存它们。当第一次使用某个字符串直接量时,JVM会将它放入字符串池中进行缓存。在一般情况下,字符串池中的字符串对象不会被垃圾回收。当程序再次需要使用该字符串时,无需重新创建一个新的字符串就可以直接让引用变量直接指向字符串中已有的字符串。而使用new操作创建的字符串对象不指向字符串池中的对象,但是可以使用intern方法使其指向字符串池中的对象。
貌似上面那样不能证明!sorry
综上:四个对象。
注:楼上有说StringBuilder对象的,个人对这个不太了解,没有发言权。
"1"、"2"、"12"、new String() 或者对象b。
"1","2","12"在堆内存空间中都是匿名对象,一个字符串就是一个匿名对象,所以这里有3个匿名对象。new String()创建新的对象被b引用。
这个大家在这里猜来猜去的没意思,自己写个程序,编译下,然后再拿class文件反编译下就OK了,下面是我反编译的结果public class Test
{
public static void main(String[] args)
{
String b = new String("1" + "2");
}
}
进入bin目录,执行javap -c -l -verbose Test
结果如下:Compiled from "Test.java"
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 3
major version: 45
Constant pool:
const #1 = class #2; // Test
const #2 = Asciz Test;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz <init>;
const #6 = Asciz ()V;
const #7 = Asciz Code;
const #8 = Method #3.#9; // java/lang/Object."<init>":()V
const #9 = NameAndType #5:#6;// "<init>":()V
const #10 = Asciz LineNumberTable;
const #11 = Asciz LocalVariableTable;
const #12 = Asciz this;
const #13 = Asciz LTest;;
const #14 = Asciz main;
const #15 = Asciz ([Ljava/lang/String;)V;
const #16 = class #17; // java/lang/String
const #17 = Asciz java/lang/String;
const #18 = String #19; // 12
const #19 = Asciz 12;
const #20 = Method #16.#21; // java/lang/String."<init>":(Ljava/lang/String;)V
const #21 = NameAndType #5:#22;// "<init>":(Ljava/lang/String;)V
const #22 = Asciz (Ljava/lang/String;)V;
const #23 = Asciz args;
const #24 = Asciz [Ljava/lang/String;;
const #25 = Asciz b;
const #26 = Asciz Ljava/lang/String;;
const #27 = Asciz SourceFile;
const #28 = Asciz Test.java;{
public Test();
LineNumberTable:
line 1: 0 LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTest;
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0 LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTest;
public static void main(java.lang.String[]);
LineNumberTable:
line 5: 0
line 6: 10 LocalVariableTable:
Start Length Slot Name Signature
0 11 0 args [Ljava/lang/String;
10 1 1 b Ljava/lang/String;
Code:
Stack=3, Locals=2, Args_size=1
0: new #16; //class java/lang/String
3: dup
4: ldc #18; //String 12
6: invokespecial #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
LineNumberTable:
line 5: 0
line 6: 10 LocalVariableTable:
Start Length Slot Name Signature
0 11 0 args [Ljava/lang/String;
10 1 1 b Ljava/lang/String;
}
重点在ldc #18; //String 12,编译器直接给你把2个字符串合并成一个字符串,放在了常量区
const #18 = String #19; // 12
const #19 = Asciz 12;纵观整个反编译的结果,没有发现单独的1或者2以上证据足以说明问题了。
谢谢你的细致回复,但是我对javap -c -l -verbose Test这个命令如何操作,以及最后生成的内容不是很懂,能不能给出一些简单讲解。小弟在此谢过啦
在bin目录下
-c -l -verbose Test
-c 输出分解后的代码,例如,类中每一个方法内,包含java字节码的指令,
-l 输出行和变量的表
-verbose 输出栈大小,方法参数的个数
Text是反编译的class文件
这个解释非常到位,更多的参数可以用javap -?来获得,E文的,耐心看一下,基本就都了解了另外,LZ记得结贴~~