该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-30
slaser 写道 这个问题对java应用几乎没什么意义。
正解。。 不过多了解下 jvm 对我们coding有好处 |
|
返回顶楼 | |
发表时间:2010-09-30
了解这些对一般程序员确实有难度,我要疯啦。。。。。。
|
|
返回顶楼 | |
发表时间:2010-09-30
搞这个除了面试还有啥意义呢?基本上我只知道怎么用才是正确的,然后我就一直这样用,没有必要用个东西都要一个个的拆零部件似的,看电视的时候,你有必要去想里面的某个晶体管是怎么制作出来的,用的啥材料吗?
|
|
返回顶楼 | |
发表时间:2010-09-30
allskylove 写道 哎!javaeye会员没有人性啊,怎么回事,我发表了一篇帖子,哈哈,把我的帖子弄成了隐藏贴,30分不见了,我看帖子浏览次数总共才10此呀! 狗日的javaeye! 哈哈!一点自由都没有,培训出来的这些枪手!
兄弟点背啊,刚好10个人看了,就投了10个隐藏贴! 我觉得不是枪手的问题,而是je上人的问题! 我的帖子也多次被评为隐藏贴了,fuc! 有问题大家一起来讨论讨论嘛(不是纯粹的提问,那就不好放到提问频道上去了吧),知道的,说个方法,不想说的不看也可以,干嘛投个隐藏贴呢?javaeye就不应该设置这样的东西! |
|
返回顶楼 | |
发表时间:2010-09-30
当然很有意义,那个allsky说的简直就是废话,lz已经说了你想解释的,
不就是第一次去看这段string常量池中有没有被创建,有就返回一个引用。 lz的那段汇编解释的很清楚了。 |
|
返回顶楼 | |
发表时间:2010-09-30
声明一个String 本来还懂点 看完之后 迷糊了。。。。。
|
|
返回顶楼 | |
发表时间:2010-09-30
其实,这个题目意义在于场景。对于一般的开发没有什么意义,如果是高性能系统的话,情况就不同了。
我举个例子,我想很多人没有过String#intern 方法。 想起Robbin的一句话,现在知识体系全面正的不多。 利用技术看场景,但是前提是你要了解本质问题是什么。回到这里,对Heap和Permanent分别的作用是什么,到底存放了什么东西。Heap又有多少内置的区域等等。可能理论上知晓,可任何理论都是要用于实处的,不是只为简单记忆和临时面试。 |
|
返回顶楼 | |
发表时间:2010-09-30
这么咬文嚼字有啥意思呢......说不定人家本来就是想问涉及到几个变量而已
|
|
返回顶楼 | |
发表时间:2010-09-30
allskylove 写道 allskylove 写道 关于 String a=new String(“abc”); 究竟产生几个String对象实例问题的讨论?
首先说明: 问此题的人,其实是草包一个,是半瓶水而已,就像问中国究竟有多少人一样?中国究竟有多少人呢?这问题本身就有问题,你是说中国现在有多少人,还是新中国成立的时候有多少人?还是全球有多少中国人? 问问题之前先要明白环境是什么?上下文是什么?那么java 也一样,你不了解java语言本身,或者jvm 本质很难回答看似简单,其实并非简单的问题。往往简单的问题,比较难回答,为什么呢?因为简单的问题没有环境约束,它没有限制出环境。任何东西脱离了周围环境,就没有它存在的价值,就好比 1+1 等于2 如何证明它一样。怎么证明呢?这个问题,你首先考虑的并不是证明不证明的问题。我们要考虑它是怎么来的?这个还真难考虑。不过怎么去证明它,首先你要知道,1+1 是否是规定就等于2,如果规定的东西,不要证明,我规定了1+1 等于二 那么证明它就显得很苍白,原因很简单规定必证明的优先权高,没有方法啊,你总不能越过规定吧,这是自然规律。首先你要这自然规律的约束下发展其自己,就像你活着地球上一样,你要看清地球本身,你光这地球上是不行的。 好废话少说,开始我们的讨论: 我定义了两个类 类一:StringDemo1 public class StringDemo1 { public static void main(String[] args) { String a=new String("abc"); } } 类二:StringDemo2 public class StringDemo2 { public static void main(String[] args) { String b="abc"; String a=new String("abc"); } } 这是很简单的两个类,没有什么可解释的,唯一不同是StringDemo2 比StringDemo1多加了一行代码 String b="abc"; 换句话说是加了一个上文的环境。 有人就会问我这有什么关系呢?那么请看我下面的分析,很简单,我不会像论坛上的一些人一样,故意那么研究得深刻,把一些不明白的人往火坑里推,显得自己很高深似的。 开始动手: 步骤一: Javac 编译两个类(各位自己这命令行编译,这里就不列出了了) 步骤二: javap -c 使用此命令,这个命令可能一般人就没有使用过,自己上网查查,都是jdk命令;此命令使用的例子:javap -c StringDemo1 javap -c StringDemo2 分别这命令行敲上面的两条命令 好,下面的是我cmd 命令行的输出(你自己的输出应该也差不多) 注:我用红色的字体来注释行: D:\String>javac StringDemo1.java D:\String>javac StringDemo2.java D:\String>javap -c StringDemo1 Compiled from "StringDemo1.java" public class StringDemo1 extends java.lang.Object{ public StringDemo1(); 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 此句new 了一个对象,产生了一个对象,毫无疑问 3: dup 4: ldc #3; //String abc 此句将String abc常量值从常量池中推送至栈顶 ,那这算不算对象,当然算了,只不过时创建时间可能不是现在哦 “#” 后面的为索引地址,我们可以从索引地址可以看到,这里有#2,#3,那么String a=new String("abc"); 这是一句代码哦,可以看出此题目中这此句产生了两个String 对象。 6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin g;)V 9: astore_1 10: return } D:\String>javap -c StringDemo2 Compiled from "StringDemo2.java" public class StringDemo2 extends java.lang.Object{ public StringDemo2(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2; //String abc 此句将String abc常量值从常量池中推送至栈顶 2: astore_1 //存储变量,也就是赋值操作 3: new #3; //class java/lang/String 此句产生一个对像 6: dup 7: ldc #2; //String abc 这里很有意思哦,我们看到 #2 索引地址已经出现过来,对了,上面 code 0: 就出现过了 他只不过是把地址,引用要过来了,并没有产生String对象,也就是从Stirng常量池里面要了个地址,自己知道地址就知道他的家了哦, 那么这里就有一个问题呀?什么问题?那这样的话,多个Sting变量有可能引用一个Strng实例,那么会产生String共享不安全的问题,多线程的情况下。这个不要担心了,String是线程安全的,因为它是final 类型的,没有办法改变!哦,恍然大悟!原来这样,怪不得sun这样做,有利于减少内存浪费啊(此问题其实还会产生String碎片,那就扯远了和StringBuffere有关系了,暂不讨论)。那么这么说来String a=new String("abc"); 此句产生了一个String对象。 9: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin g;)V 12: astore_2 13: return } 总结一下吧: String a=new String("abc");这样的问题没有什么意义,脱离上下文的环境本身就没有意思了。从上面的分析,我们得出两个结论,第一个结论,也就是StringDemo1 中的请求,此句产生两个对象,其中一个特殊的String对象在String常量池里,另外一个就是对象堆中的(这个普通的Java类一样) 第二个结论,也就是StringDemo2, 那一句只产生了一个对象,只有堆中的一个对象,因为上网已经产生了一个String常量对象,后面就不产生了,直接使用地址索引了。 String 是一个特殊的数据类型,说白了它是从简单到对象类型过渡的一种类型;它既有简单类型那样的快速又有对象类型的特性。对应String的不足,那么String家族里面已经有了补充的类,完善的类,StringBuffere 各位不用担心,StringBuffere完全面向对象了,怎么证明呢?很简单 String a=“abc”; 这样可以直接复制常量值个String类型的。就好像简单类型的可以使用字面量来直接初始化 一样。例如 int a=123; StringBuffere a=“abc”; 这样就不行啦 最后的结论,1个或者2个 补充下:jvm 指令 可以参考 http://samwong.iteye.com/blog/710737 还真的没有办法了,javaeye 这群猪,我现在引用我自己写的帖子总可以吧,靠,我这这个帖子上被扣60分,日,javaeye 就是一个流氓的地方,怎么没有审核制度,真是漏洞百出。 有举报制度。JE正在向民主靠拢,所有的事情都需要举报。 |
|
返回顶楼 | |
发表时间:2010-09-30
allskylove 写道 算了,yy一下就行了,此贴没有水平! 和这些混蛋交流真是无语了,难道讨论问题非得在平静的水面上交流,中国人的表面平静,就是内心阴险的表现! 笨不出来什么大牛,大鸟,顶多就是个鸟蛋而已。
首先不讨论水平,你可以写出更好的? |
|
返回顶楼 | |