String name=new String("java"+"hello");有几个对象
解决方案 »
- 关于不同Thread中判断String是否存在
- jpanel的布局为GridBagLayout,但其中的组件有时会不明原因的缩成一团。恼火啊。。。请指教!感谢!
- 下面是我做的一个类,如何用htm显示出来
- 我的java程序用bat文件启动,现在我想实现定时启动/关闭bat文件,该怎么做?
- 最近在学java,想买本参考书。。。求大神们推荐几本。。
- Canvas对象为什么会把Menu挡住?
- 向网络服务器发送数据的方法get()和post()之间的区别
- 关于字字符串和URL编码之间转换的问题,请高手解决
- 我下载了jbuilder7,但是有30天的使用限制,真是不爽,哪位仁兄有注册码?50分相谢!
- 各位大虾,我现在再用SA(System Architect)做项目设计,有谁知道怎样用SA将Java源代码倒成类图?
- 关于构造器的疑惑
- 一些疑问,,请详细解答,
"java"+"hello"产生对象"javahello"放在常量池中 3个了
由"javahello"创建一个新对象 放在堆中 总共4个对象
String str=new String(s);
我这样也等同于这个String name=new String("java"+"hello")?
hello,java,hellojava,这三个会放到字符串常量池中。
new会创建一个对象
解析一下,这个语句的操作:
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字节。
StringBuilder昙花一现,9楼所言极当
谁告诉你不会被优化的。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
new String("hello"+"java") 会产生另一个对象。以前听到的并不是这样(大多数人应该觉得是产生了4个对象,我之前也一样),我想可能是JDK近期做的优化。用JDK5或者JDK6早期版本试试,也许会产生不同的结果。手头没有,等人实验。
"hello" 1
"java" + "hello"又产生一个对象 1
new String 是一个对象 1和20#的意思差不多但是name不应该是对象,只是一个对象的引用,所以1+1+1+1 = 4
没有"java",没有"hello",编译时会自动优化的。
谁告诉你不会被优化的。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
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"
String name=new String("java"+"hello");
会被编译成
String name=new String(new StringBuilder("java").append("hello"));
其中"java"和"hello"为常量
而name和匿名的sb为变量
故,有2个常量和2个变量,此题选A,lz看看答案是不是A?
写一个测试类,编译一下:[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: returnpublic 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 把栈中的引用赋给第一个变量
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赋值。