从其他地方移来的Java面题,欢迎讨论……

1.String a = new String("1"+"2")共建了几个对象

我相信,绝对是个经典兼考倒一堆人的题目。经典,Java的面、笔试上都会有,可又总是有人会犯晕。呵呵!

看构造器里面("1"+"2"),这个是在编译期就已经做了处理,即代表一个字符串:"12"。

当使用new的方法创建字符串时,注意这个”new“,就表示直接开辟了内存空间,VM在对其对象的值”12“;然后再把值放到VM的常量池中,并引用其本身。所以就创建了两个对象,看反编译后的代码:

 

<span style="font-size: small;">String a = new String("1"+"2");

System.out.println(a);

反编译后的:

Code:

  0:   new     #2; //class java/lang/String 在堆上创建了一个对象

  3:   dup

  4:   ldc     #3; //String 12最终的字符串值 </span>

 

   在API中对使用new创建String的建议 : 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列; 换句话说,新创建的字符串是该参数字符串的副本。

既然写到这了,就扩展开来,说说其他的情况,先说一个与题目中类似的,唯一区别是,不使用new创建

看代码:

 

<span style="font-size: small;">String str1 = "ABC" + "CD";

String str2 = new String("ABC" + "CD");</span>

 

 再看其反编译后的:

 

<span style="font-size: small;">Code:

 0:   ldc     #2; //String ABCCD

 2:   astore_1

 3:   new     #3; //class java/lang/String

 6:   dup

 7:   ldc     #2; //String ABCCD

</span>

 

 对比一下,我想大伙都能看出了两者的区别,首先是,直接定义字符串常量,VM不会自动调用new创建,而是在VM维护的常量池中先查找,如果发现,直接返回一个对其的引用,若不存在,把其加入,再返回一个对其的引用。


此外,再总结一下与String 有关的三种加法:

  • String tmp = "a" + "b" + "c";
  • String tmp = null;tmp+= "a";tmp+= "b";tmp+= "c";
  • 使用Stringbuffer或StringBuilder(注意,其在多线程环境下是不安全的)的append方法

看看:

 

<span style="font-size: small;"> Code:

START-第一种情况String str1 = "ABC" + "CD":

  0:   ldc     #2; //String ABCCD

  2:   astore_1

  END-第一种情况

 

  START-第二种情况:String str2 = null;str2 += "ABC";str2 += "CDS";str2 += "DSS";

  3:   aconst_null

  4:   astore_2

  5:   new     #3; //class java/lang/StringBuilder:   创建了一个StringBuilder对象

  8:   dup

  9:   invokespecial   #4; 

  12:  aload_2

  13:  invokevirtual   #5; 

  16:  ldc     #6; //String ABC : 追加第一个字符串"ABC",调用了append方法,下看

  18:  invokevirtual   #5; //Method append:

  21:  invokevirtual   #7; //Method toString:

 

  24:  astore_2

  25:  new     #3; //class java/lang/StringBuilder: 再创建了一个StringBuilder对象

  28:  dup

  29:  invokespecial   #4; 

  32:  aload_2

  33:  invokevirtual   #5; 先追加前面的字符串 "ABC"

  36:  ldc     #8; //String CDS : 追加第二个字符串"CDS",调用了append方法,下看

  38:  invokevirtual   #5; //Method java/lang/StringBuilder.append:

  41:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:

  44:  astore_2

 

  45:  new     #3; //class java/lang/StringBuilder:再创建了一个StringBuilder对象

  48:  dup

  49:  invokespecial   #4; 

  52:  aload_2

  53:  invokevirtual   #5; //Method java/lang/StringBuilder.append: 先追加前面的字符串"ABC CDS"

  56:  ldc     #9; //String DSS:追加第三个字符串"CDS",调用了append方法,下看

  58:  invokevirtual   #5; //Method java/lang/StringBuilder.append:

  61:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:

  END-第二种情况

 

  START-第三种情况

  64:  astore_2  

  65:  new     #10; //class java/lang/StringBuffer:创建StringBuffer对象

  68:  dup

  69:  invokespecial   #11; //Method java/lang/StringBuffer."<init>":()V

  72:  astore_3

  73:  aload_3

  74:  ldc     #6; //String ABC : 调用append方法

  76:  invokevirtual   #12; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;

  79:  pop

  80:  aload_3

  81:  ldc     #13; //String DDD:调用append方法

  83:  invokevirtual   #12; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;

  86:  pop

  END-第三种情况</span>

 

小结一把:在JVM中,出现了第二种情况的,会默认创建一个StringBuilder对象来对字符串进行追加,注意,每一个"+="操作符,就会创建一个新的StringBuilder对象。这里就会造成挺大的内存浪费。

而用StringBuffer/StringBuilder这个对象来实现追加,在没调用其toString方法时,其对象还是可变的,一旦调用了toString的方法,就变成了不可变的String。



2. 触发器有几种?表和视图的区别
3.hibernate中导入(导出?忘记是导入还是导出了)大量数据时,会产生大量的对象,为了避免这一现象应该怎么做?
4.struts的作用, 被用做c层的原理
5.Spring的ioc的好处
6.事务的操作步骤(不大明白这个题目的意思),为什么会有事务


这里有某位仁兄( charles_wang8888)的解答,个人感觉其答得好:

第一题,创建了2个对象,由于编译器会吧等号右边的进行合并,所以他在常量区会建立一个 "12’的字符串,然后,在堆上创建一个对象叫a .
第 二题:日志类触发器吧,其他我不太清楚,表和视图的区别。表是在数据库的存储,视图是某些数据库语句,它不会对应数据库的存储。。表是内模式,视图是外模 式。
第三题:hibernate中导入大量对象,可以采用VO模式来优化网络交通
第4题:struts的作用是更好的反应出MVC模式, 具体你看书吧,这东西不太好回答,太开放了。
第5题目:SPRING 的IOC,控制反转,好处是通过配置来维持对象之间的关系,而不是让这些关系写死在代码中。这样对象之间的耦合程度被降低到最低
第6题:事务的操 作步骤。。不明白。威为什么要有事务。。可以吧多个步骤方在一起,让他们整体作为一个原子,要么一起成功,要么一起失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值