本帖最后由 java2000_net 于 2008-04-15 14:26:47 编辑

解决方案 »

  1.   

    嗯,第一个理论上就是应该为True的。第二个可能是虚拟机实现上在语法分析结果处理上的问题,这种问题不必太在乎,因为在Java里比较对象就不该用==
    Java里面除了几种类型的值,都不应该用==,
    那么为啥要把这个事情搞得很清楚呢?而第二个未必应该就是false的。
      

  2.   

    System.out.println(c==e);//false? 
    改成System.out.println(d==e);//false? 
      

  3.   

    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方法而不是==。实际应用中也基本上不会用到==比较字符串(实际是比较引用)的情况。
      

  4.   

    好吧,这么说吧,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成员就可以了。