各位,下面的代码为什么?【对Java编译器优化的一点点认识】 本帖最后由 java2000_net 于 2008-04-15 14:26:47 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 嗯,第一个理论上就是应该为True的。第二个可能是虚拟机实现上在语法分析结果处理上的问题,这种问题不必太在乎,因为在Java里比较对象就不该用==Java里面除了几种类型的值,都不应该用==,那么为啥要把这个事情搞得很清楚呢?而第二个未必应该就是false的。 System.out.println(c==e);//false? 改成System.out.println(d==e);//false? String b = "ab" + "c"; 这是常量运算,编译期就优化成"abc"了,和String b = "abc"是一样的结果。编译器找到有"abc"这个字符串,所以直接把其引用赋给b,而这个字符串原本已经赋了一个引用给a,所以a == b。String d=c+"ef";这个d是运行的时候才产生的,是由c字符串和"ef"通过连接运行得到的新的String对象,String e="cdef"; e是编译期产生的,和b所引用的新的字符串对象不同。其实要把这个事情搞清楚意义不大。比较字符串本来就应该使用equals方法而不是==。实际应用中也基本上不会用到==比较字符串(实际是比较引用)的情况。 好吧,这么说吧,Java是编译型语言。无论他的语法分析是Yacc的生成,还是手工的。都会解析到这样的语法。String a = "abc"; String b = "ab" + "c"; 那么它们会做什么呢? 解析到抽象语法树中,用伪码说,就是a = "abc";b = "ab" + "c"注意,这个时候是编译中,而且处于前端,还没有到把语法树转化为字节码的阶段呢。那么发现"ab" 和 "c"都是字符串常量。那么Yacc当然有能力把他变成"abc"了。也就是说,当你看到了MyClass.class的时候,"abc"都已经生米煮成了熟饭了,是个板上钉钉的事情了。而另外一个不一样。d = c + "ef"这个语法树不能进行,因为c是变量,不是常量或者是字面量。c在运行过程中,可能会被修改掉,比如这句之前,或者其他的线程。我们这个语言,是上下文无关的问法。现在绝大多数的语言都是这类的。那么既然都是"abc"了。被JVM加载起来。那么就可以让String的实现类指向同一块 “内存地址”(这个理论上未必是真实的虚拟内存地址的,有些帖子说什么内存地址相等,我并不是很确定这个事情,我觉得要加个引号,如果说Ruby是内存相等,我信,源码很明显,就是Ruby语法给C语言加个壳子。)所以结果是个true。最后,这个事情不要太认真,绝对没有意义的Java问题。a = "abc"b = "abcd"你说a==b ?这个在java的虚拟机上是不等,但是我以为,修改了Java的String实现,就可以让它相等,只要再聚合一个offset成员就可以了。 正则表达式如何把String截取位定长的字符数组? 手机归属地 画的弧闪一下就不见了? 用java实现随机选择按钮 看不懂javap -verbose得到的结果,高手进来注释一下.(另外开贴给分.) 这两块数据是一样的吗? 求助:在JAVA里面怎样提取出汉字里的各个字节??? 谁有Jcreator的注册码? 想学java,请推荐几本好书和下载地址 什么叫中间包(件)?----初学者 约瑟夫环程序添加界面 在java中怎样使用jasperreport来实现自动打印?
Java里面除了几种类型的值,都不应该用==,
那么为啥要把这个事情搞得很清楚呢?而第二个未必应该就是false的。
改成System.out.println(d==e);//false?
这是常量运算,编译期就优化成"abc"了,和String b = "abc"是一样的结果。编译器找到有"abc"这个字符串,所以直接把其引用赋给b,而这个字符串原本已经赋了一个引用给a,所以a == b。String d=c+"ef";
这个d是运行的时候才产生的,是由c字符串和"ef"通过连接运行得到的新的String对象,
String e="cdef";
e是编译期产生的,和b所引用的新的字符串对象不同。其实要把这个事情搞清楚意义不大。比较字符串本来就应该使用equals方法而不是==。实际应用中也基本上不会用到==比较字符串(实际是比较引用)的情况。
无论他的语法分析是Yacc的生成,还是手工的。都会解析到这样的语法。
String a = "abc";
String b = "ab" + "c"; 那么它们会做什么呢? 解析到抽象语法树中,用伪码说,就是
a = "abc";
b = "ab" + "c"注意,这个时候是编译中,而且处于前端,还没有到把语法树转化为字节码的阶段呢。
那么发现"ab" 和 "c"都是字符串常量。那么Yacc当然有能力把他变成"abc"了。也就是说,当你看到了MyClass.class的时候,"abc"都已经生米煮成了熟饭了,是个板上钉钉的事情了。而另外一个不一样。
d = c + "ef"
这个语法树不能进行,因为c是变量,不是常量或者是字面量。c在运行过程中,可能会被修改掉,比如这句之前,或者其他的线程。
我们这个语言,是上下文无关的问法。现在绝大多数的语言都是这类的。那么既然都是"abc"了。
被JVM加载起来。那么就可以让String的实现类指向同一块 “内存地址”(这个理论上未必是真实的虚拟内存地址的,有些帖子说什么内存地址相等,我并不是很确定这个事情,我觉得要加个引号,如果说Ruby是内存相等,我信,源码很明显,就是Ruby语法给C语言加个壳子。)
所以结果是个true。最后,这个事情不要太认真,绝对没有意义的Java问题。
a = "abc"
b = "abcd"
你说a==b ?
这个在java的虚拟机上是不等,但是我以为,修改了Java的String实现,就可以让它相等,只要再聚合一个offset成员就可以了。