当前位置:编程学习 > JAVA >>

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

String name=new String("java"+"hello");有几个对象 String --------------------编程问答-------------------- 目测3个,java,hello,javahello?求指教 --------------------编程问答-------------------- 我也认为是3个 --------------------编程问答-------------------- 目测4个 --------------------编程问答-------------------- 求解释,求解释 --------------------编程问答-------------------- 常量池中开始有"java""hello"     2个
"java"+"hello"产生对象"javahello"放在常量池中 3个了
由"javahello"创建一个新对象 放在堆中   总共4个对象
   --------------------编程问答--------------------
引用 5 楼 fudongrifdr 的回复:
常量池中开始有"java""hello"     2个
"java"+"hello"产生对象"javahello"放在常量池中 3个了
由"javahello"创建一个新对象 放在堆中   总共4个对象
  
选项有2,3,4,5。   3,4都错了 --------------------编程问答--------------------
引用 6 楼 shouliezhe1hao 的回复:
Quote: 引用 5 楼 fudongrifdr 的回复:

常量池中开始有"java""hello"     2个
"java"+"hello"产生对象"javahello"放在常量池中 3个了
由"javahello"创建一个新对象 放在堆中   总共4个对象
  
选项有2,3,4,5。   3,4都错了
题目就是你这样的?那我就不清楚了 --------------------编程问答-------------------- 2个好不好 --------------------编程问答-------------------- string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下 --------------------编程问答--------------------
引用 9 楼 fangmingshijie 的回复:
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
怎么查看呀 --------------------编程问答--------------------
引用 9 楼 fangmingshijie 的回复:
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
--------------------编程问答--------------------
引用 11 楼 fudongrifdr 的回复:
Quote: 引用 9 楼 fangmingshijie 的回复:

string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
String s="hello"+"java";
    String str=new String(s);
我这样也等同于这个String name=new String("java"+"hello")? --------------------编程问答--------------------
引用 1 楼 haoran_10 的回复:
目测3个,java,hello,javahello?求指教
http://jiangzhengjun.iteye.com/blog/577039可以看这个 --------------------编程问答--------------------
引用 13 楼 shouliezhe1hao 的回复:
Quote: 引用 1 楼 haoran_10 的回复:

目测3个,java,hello,javahello?求指教
http://jiangzhengjun.iteye.com/blog/577039可以看这个

按这个文章看 , 是2个   但解释跟9L的不一样   --------------------编程问答-------------------- 4个对象:
hello,java,hellojava,这三个会放到字符串常量池中。
new会创建一个对象 --------------------编程问答-------------------- 我觉得是4个。。。前段时间正好看到过这个问题,但是忘记在那里看到的了 --------------------编程问答-------------------- String name=new String("java"+"hello");
解析一下,这个语句的操作:
String类在Java中是比较特殊的,允许使用""的方式来创建对象,
另外,在JVM的运行时内存区的方法区中,会维护各个基础类型及String的常量池
因些:
1."java"创建了一个对象,存于String常量池
2."hello"创建了一个对象,存于String常量池
3."java"+"hello",创建了一个对象,存于常量池(基于字符串的+操作,如带有引用的,将在堆中创建对象,否则值会存于字符常量池)
4.new将会创建一个对象,将字符常量池中的"javahello"复制到堆中
此例将创建4个对象 --------------------编程问答-------------------- 可以这样理解:
对象只有一个:new String("javahello"),存在于堆内存中,所占的空间大于Object的12字节;
常量区中有三个:"java" "hello" "javahello",严格意义上讲,他们并不是“对象”,只是三个“连续内存空间”,由于char占一个字节,所以他们分别占用4、5、9个字节;
栈区有一个unsigned int类型指针name,占4字节。 --------------------编程问答-------------------- 到底是几个对象呢 --------------------编程问答-------------------- 貌似是五个,name=new String("java"+"hello"),首先常量池中有java,hello两个,"java"+"hello"连接成"javahello"也放在常量池中,目前常量池只有三个,new的时候会在堆中开辟一段内存用来存放"javahello"对象,同时在栈中生成一个name对象指向堆内存中的"javahello"对象,所以共5个 --------------------编程问答--------------------
引用 20 楼 qq1145174853 的回复:
貌似是五个,name=new String("java"+"hello"),首先常量池中有java,hello两个,"java"+"hello"连接成"javahello"也放在常量池中,目前常量池只有三个,new的时候会在堆中开辟一段内存用来存放"javahello"对象,同时在栈中生成一个name对象指向堆内存中的"javahello"对象,所以共5个

栈中的name不是对象,是一个引用 --------------------编程问答-------------------- 个人觉得是4个 --------------------编程问答-------------------- 4个,多出来我就吃了

167765087 -> come on qq group --------------------编程问答-------------------- String对象两个都是javahello分别在常量区和堆里
StringBuilder昙花一现,9楼所言极当 --------------------编程问答-------------------- 我绝对不会告诉你,我已经有N年没有考试了。而面试,也基本不会出现这种问题。好吧,我是来学习的,顺带打酱油。 --------------------编程问答-------------------- 我觉得是两个吧,java会对一些特殊情况进行特殊处理,“hello+java" 这种情况java会进行特殊处理,变成“hellojava”在创建对象,所以,“hello+java"只创建一个对象,叫上前面的创建的对象,一共两个 --------------------编程问答-------------------- 菜鸟级别的新手请大家指点... --------------------编程问答-------------------- 应该是2个吧,像"java"+"hello" java会自己先优化的,会合并成一个对象"javahello"的,然后在字符串池中保留,然后new的时候再在堆中创建新的对象。 --------------------编程问答--------------------
引用 28 楼 gb19861012 的回复:
应该是2个吧,像"java"+"hello" java会自己先优化的,会合并成一个对象"javahello"的,然后在字符串池中保留,然后new的时候再在堆中创建新的对象。
写在构造方法里的字符串拼接 不会被优化 看来是4个 --------------------编程问答-------------------- String 这个类本身,算不算一个对象呢? --------------------编程问答-------------------- 那就是2个了 字面字符串采用string静态缓冲池优化了,不产生对象。 --------------------编程问答--------------------
引用 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
--------------------编程问答-------------------- "hello" + "java" <= 只会在常量池产生一个对象"hellojava",这是编译器做的优化。
new String("hello"+"java") 会产生另一个对象。

以前听到的并不是这样(大多数人应该觉得是产生了4个对象,我之前也一样),我想可能是JDK近期做的优化。用JDK5或者JDK6早期版本试试,也许会产生不同的结果。手头没有,等人实验。 --------------------编程问答--------------------
引用 33 楼 lcf 的回复:
"hello" + "java" <= 只会在常量池产生一个对象"hellojava",这是编译器做的优化。
new String("hello"+"java") 会产生另一个对象。

以前听到的并不是这样(大多数人应该觉得是产生了4个对象,我之前也一样),我想可能是JDK近期做的优化。用JDK5或者JDK6早期版本试试,也许会产生不同的结果。手头没有,等人实验。

只要是正式发布的JDK,都是这个结果。 --------------------编程问答-------------------- new string还是不错的啊 --------------------编程问答-------------------- String name=new String("java"+"hello");

"java"  1
"hello" 1
"java" + "hello"又产生一个对象  1
new String 是一个对象   1

和20#的意思差不多
引用
貌似是五个,name=new String("java"+"hello"),首先常量池中有java,hello两个,"java"+"hello"连接成"javahello"也放在常量池中,目前常量池只有三个,new的时候会在堆中开辟一段内存用来存放"javahello"对象,同时在栈中生成一个name对象指向堆内存中的"javahello"对象,所以共5个


但是name不应该是对象,只是一个对象的引用,所以1+1+1+1 = 4 --------------------编程问答-------------------- 我很确定答案只有2个,由于常量字符串是在编译的时候就也被确定的,又因"java"和"hello"都是常量,因此变量”java“+”hello“的值在编译时就可以确定。一个对象是字符串常量,一个是创建一个新的对象在堆中。 --------------------编程问答-------------------- 2个。
没有"java",没有"hello",编译时会自动优化的。 --------------------编程问答-------------------- 怎么,老衲觉得也是4个对象呢,施主,需要化缘么。。。 --------------------编程问答--------------------
引用 32 楼 forgetsam 的回复:
Quote: 引用 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


 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 --------------------编程问答--------------------  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

你拿个这东西来搞笑吗?它就是不优化能把加号放到引号里面去?

"abc+dbc" --------------------编程问答-------------------- 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? --------------------编程问答-------------------- 两个,"java" + "hello"在编译时确定并优化自动将两个合并成"javahello",创建该对象并放入常量池,另一个就是new了。 --------------------编程问答-------------------- 抛开基础知识不论,就算从动手能力来说,你们能试试在来发言吗?
写一个测试类,编译一下:

[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 把栈中的引用赋给第一个变量 --------------------编程问答--------------------
引用 8 楼 fangmingshijie 的回复:
2个好不好
我也觉得是两个"java"+"hello"在这里面只能算是一个栈 --------------------编程问答--------------------
引用 9 楼 fangmingshijie 的回复:
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下

这个是jdk1.5以后的吧 --------------------编程问答--------------------
引用 9 楼 fangmingshijie 的回复:
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下


受教 --------------------编程问答-------------------- 按44楼的意思。这个实际上是创建了两个对象吗? --------------------编程问答-------------------- 源码:
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


}
--------------------编程问答-------------------- 两个对象:
常量值中一个javahello,如上红色部分。
T.name一个,如上蓝色部分。

如上黄色部分:用常量javahello对T.name赋值。 --------------------编程问答-------------------- 2个 javaHello与new出来的对象 --------------------编程问答-------------------- 2个,javahello是一个对象,然后new出的String是一个对象 --------------------编程问答-------------------- 看完此贴受教了!
实际上根据Java内存模型的理解,应该是4个对象的。
但是由于Java编译器对常量的优化处理,实际上只有2个对象。

但是要说4个错了,个人认为也没错,因为2这个答案是依赖于编译器的东西,优化过程是没有规范的,也就是说有可能编译器版本和厂商的不同,产生不同结果!

另外,HinanaiTenshi 讲的很对,多注重动手能力,学习了

补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,