String name=new String("java"+"hello");有几个对象

shouliezhe1hao 2013-08-03 06:03:37
String name=new String("java"+"hello");有几个对象
...全文
1318 55 打赏 收藏 转发到动态 举报
写回复
用AI写文章
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
Seachal 2016-04-22
  • 打赏
  • 举报
回复
常量池中开始有"java""hello" 2个 "java"+"hello"产生对象"javahello"放在常量池中 3个了 由"javahello"创建一个新对象 放在堆中 总共4个对象
陈靓仔 2016-04-22
  • 打赏
  • 举报
回复
引用 44 楼 HinanaiTenshi 的回复:
抛开基础知识不论,就算从动手能力来说,你们能试试在来发言吗? 写一个测试类,编译一下:

[root@hina stringtest]# more TestString.java 
public class TestString{
public static void main(String[] args) {
String name = new String("java" + "hello");
}
}
[root@hina stringtest]# javac TestString.java
[root@hina stringtest]# javap -c TestString
上面这段javap -c打编译后的字节码 插一句,论坛里多数是靠java吃饭的,如果不看下面的内容,对编译的字节码没有一个大概的结论,那你们未免太不把自己的工作和前途当一回事了。

Compiled from "TestString.java"
public class TestString extends java.lang.Object{
public TestString();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

public static void main(java.lang.String[]);
  Code:
   0:	new	#2; //class java/lang/String
   3:	dup
   4:	ldc	#3; //String javahello
   6:	invokespecial	#4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
   9:	astore_1
   10:	return

}
看清楚了,编译的字节码里没有java也没有hello,而是javahello。这个javahello不是在执行的时候被创建,而是jvm启动的时候初始化好的。 实际上只有一个new,也就是说只创建了一个对象: 0 new 创建string对象 3 dup 复制顶栈内容,这是所有new对象都会做的事情,因为jvm要做<init> 4 ldc 把常量池中javahello的引用压入栈中 6 invokespecial 对象初始化 9 astore_1 把栈中的引用赋给第一个变量
“javahello”和new不就是2个了?怎么不把“javahello”算上...
gaobaiy 2013-08-09
  • 打赏
  • 举报
回复
看完此贴受教了! 实际上根据Java内存模型的理解,应该是4个对象的。 但是由于Java编译器对常量的优化处理,实际上只有2个对象。 但是要说4个错了,个人认为也没错,因为2这个答案是依赖于编译器的东西,优化过程是没有规范的,也就是说有可能编译器版本和厂商的不同,产生不同结果! 另外,HinanaiTenshi 讲的很对,多注重动手能力,学习了
wufei151 2013-08-09
  • 打赏
  • 举报
回复
2个,javahello是一个对象,然后new出的String是一个对象
forgetsam 2013-08-08
  • 打赏
  • 举报
回复
public static void main(java.lang.String[] args); 0 new java.lang.String [24] 3 dup 4 ldc <String "abc+dbc"> [26] 6 invokespecial java.lang.String(java.lang.String) [28] 9 astore_1 [s] 10 return Line numbers: [pc: 0, line: 13] [pc: 10, line: 17] Local variable table: [pc: 0, pc: 11] local: args index: 0 type: java.lang.String[] [pc: 10, pc: 11] local: s index: 1 type: java.lang.String[/quote] 你拿个这东西来搞笑吗?它就是不优化能把加号放到引号里面去? "abc+dbc"
hippoppower 2013-08-08
  • 打赏
  • 举报
回复
引用 32 楼 forgetsam 的回复:
引用 29 楼 hippoppower 的回复:
[quote=引用 28 楼 gb19861012 的回复:] 应该是2个吧,像"java"+"hello" java会自己先优化的,会合并成一个对象"javahello"的,然后在字符串池中保留,然后new的时候再在堆中创建新的对象。
写在构造方法里的字符串拼接 不会被优化 看来是4个
谁告诉你不会被优化的。
public static void main(String[] args) {
	String nnn = new String("abcd"+"xyz");

}

我这里看没有优化啊

 public static void main(java.lang.String[] args);
     0  new java.lang.String [16]
     3  dup
     4  ldc <String "abcdxyz"> [18]
     6  invokespecial java.lang.String(java.lang.String) [20]
     9  astore_1 [nnn]
    10  return
      Line numbers:
        [pc: 0, line: 9]
        [pc: 10, line: 11]
      Local variable table:
        [pc: 0, pc: 11] local: args index: 0 type: java.lang.String[]
        [pc: 10, pc: 11] local: nnn index: 1 type: java.lang.String
[/quote] public static void main(java.lang.String[] args); 0 new java.lang.String [24] 3 dup 4 ldc <String "abc+dbc"> [26] 6 invokespecial java.lang.String(java.lang.String) [28] 9 astore_1 [s] 10 return Line numbers: [pc: 0, line: 13] [pc: 10, line: 17] Local variable table: [pc: 0, pc: 11] local: args index: 0 type: java.lang.String[] [pc: 10, pc: 11] local: s index: 1 type: java.lang.String
螃蟹变异了 2013-08-08
  • 打赏
  • 举报
回复
2个 javaHello与new出来的对象
火影之贺 2013-08-08
  • 打赏
  • 举报
回复
两个对象: 常量值中一个javahello,如上红色部分。 T.name一个,如上蓝色部分。 如上黄色部分:用常量javahello对T.name赋值。
火影之贺 2013-08-08
  • 打赏
  • 举报
回复
源码:
class T
{
		String name= new String("java"+"hello"); 	
}
T.class反编译后: E:\>javap -verbose T Compiled from "T.java" class T extends java.lang.Object SourceFile: "T.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #7.#16; // java/lang/Object."<init>":()V const #2 = class #17; // java/lang/String const #3 = String #18; // javahello const #4 = Method #2.#19; // java/lang/String."<init>":(Ljava/lang/String ;)V const #5 = Field #6.#20; // T.name:Ljava/lang/String; const #6 = class #21; // T const #7 = class #22; // java/lang/Object const #8 = Asciz name; const #9 = Asciz Ljava/lang/String;; const #10 = Asciz <init>; const #11 = Asciz ()V; const #12 = Asciz Code; const #13 = Asciz LineNumberTable; const #14 = Asciz SourceFile; const #15 = Asciz T.java; const #16 = NameAndType #10:#11;// "<init>":()V const #17 = Asciz java/lang/String; const #18 = Asciz javahello; const #19 = NameAndType #10:#23;// "<init>":(Ljava/lang/String;)V const #20 = NameAndType #8:#9;// name:Ljava/lang/String; const #21 = Asciz T; const #22 = Asciz java/lang/Object; const #23 = Asciz (Ljava/lang/String;)V; { java.lang.String name; T(); Code: Stack=4, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: aload_0 5: new #2; //class java/lang/String 8: dup 9: ldc #3; //String javahello 11: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin g;)V 14: putfield #5; //Field name:Ljava/lang/String; 17: return LineNumberTable: line 1: 0 line 3: 4 }
Carina_workHard 2013-08-08
  • 打赏
  • 举报
回复
按44楼的意思。这个实际上是创建了两个对象吗?
BigQiu66 2013-08-08
  • 打赏
  • 举报
回复
引用 9 楼 fangmingshijie 的回复:
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
受教
java_freshman01 2013-08-08
  • 打赏
  • 举报
回复
引用 9 楼 fangmingshijie 的回复:
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
这个是jdk1.5以后的吧
君斗one 2013-08-08
  • 打赏
  • 举报
回复
引用 8 楼 fangmingshijie 的回复:
2个好不好
我也觉得是两个"java"+"hello"在这里面只能算是一个栈
HinanaiTenshi 2013-08-08
  • 打赏
  • 举报
回复
抛开基础知识不论,就算从动手能力来说,你们能试试在来发言吗? 写一个测试类,编译一下:

[root@hina stringtest]# more TestString.java 
public class TestString{
public static void main(String[] args) {
String name = new String("java" + "hello");
}
}
[root@hina stringtest]# javac TestString.java
[root@hina stringtest]# javap -c TestString
上面这段javap -c打编译后的字节码 插一句,论坛里多数是靠java吃饭的,如果不看下面的内容,对编译的字节码没有一个大概的结论,那你们未免太不把自己的工作和前途当一回事了。

Compiled from "TestString.java"
public class TestString extends java.lang.Object{
public TestString();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

public static void main(java.lang.String[]);
  Code:
   0:	new	#2; //class java/lang/String
   3:	dup
   4:	ldc	#3; //String javahello
   6:	invokespecial	#4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
   9:	astore_1
   10:	return

}
看清楚了,编译的字节码里没有java也没有hello,而是javahello。这个javahello不是在执行的时候被创建,而是jvm启动的时候初始化好的。 实际上只有一个new,也就是说只创建了一个对象: 0 new 创建string对象 3 dup 复制顶栈内容,这是所有new对象都会做的事情,因为jvm要做<init> 4 ldc 把常量池中javahello的引用压入栈中 6 invokespecial 对象初始化 9 astore_1 把栈中的引用赋给第一个变量
sca4441479 2013-08-08
  • 打赏
  • 举报
回复
两个,"java" + "hello"在编译时确定并优化自动将两个合并成"javahello",创建该对象并放入常量池,另一个就是new了。
owen1759 2013-08-08
  • 打赏
  • 举报
回复
9楼正解 String name=new String("java"+"hello"); 会被编译成 String name=new String(new StringBuilder("java").append("hello")); 其中"java"和"hello"为常量 而name和匿名的sb为变量 故,有2个常量和2个变量,此题选A,lz看看答案是不是A?
「已注销」 2013-08-06
  • 打赏
  • 举报
回复
2个。 没有"java",没有"hello",编译时会自动优化的。
morelzh 2013-08-06
  • 打赏
  • 举报
回复
我很确定答案只有2个,由于常量字符串是在编译的时候就也被确定的,又因"java"和"hello"都是常量,因此变量”java“+”hello“的值在编译时就可以确定。一个对象是字符串常量,一个是创建一个新的对象在堆中。
liaohanlu 2013-08-06
  • 打赏
  • 举报
回复
怎么,老衲觉得也是4个对象呢,施主,需要化缘么。。。
lcf 2013-08-05
  • 打赏
  • 举报
回复
"hello" + "java" <= 只会在常量池产生一个对象"hellojava",这是编译器做的优化。 new String("hello"+"java") 会产生另一个对象。 以前听到的并不是这样(大多数人应该觉得是产生了4个对象,我之前也一样),我想可能是JDK近期做的优化。用JDK5或者JDK6早期版本试试,也许会产生不同的结果。手头没有,等人实验。
加载更多回复(35)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧