首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Java好玩儿的知识点

2012-12-27 
Java有意思的知识点今天在论坛上看到的几个题,有几个貌似还挺有意思的。 public static void test() {Strin

Java有意思的知识点
今天在论坛上看到的几个题,有几个貌似还挺有意思的。

 public static void test() {      String x = "hello";      String y = "world";      String z = new String("helloworld");      String a = "helloworld";     System.out.println("x == hello:" + (x == "hello"));      System.out.println("a == helloworld:" + (a == "hello" + "world"));      System.out.println("a == x+y:" + (a == (x + y)));  }  

x == hello:true
a == helloworld:true
a == x+y:false
请看翻译过的源码:
public static void test();      0  ldc <String "hello"> [15]      2  astore_0 [x]      3  ldc <String "world"> [17]      5  astore_1 [y]      6  ldc <String "helloworld"> [19]      8  astore_2 [a]      9  getstatic java.lang.System.out : java.io.PrintStream [21]     12  new java.lang.StringBuilder [27]     15  dup     16  ldc <String "x == hello:"> [29]     18  invokespecial java.lang.StringBuilder(java.lang.String) [31]     21  aload_0 [x]     22  ldc <String "hello"> [15]     24  if_acmpne 31     27  iconst_1     28  goto 32     31  iconst_0     32  invokevirtual java.lang.StringBuilder.append(boolean) : java.lang.StringBuilder [34]     35  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [38]     38  invokevirtual java.io.PrintStream.println(java.lang.String) : void [42]     41  getstatic java.lang.System.out : java.io.PrintStream [21]     44  new java.lang.StringBuilder [27]     47  dup     48  ldc <String "a == helloworld:"> [47]     50  invokespecial java.lang.StringBuilder(java.lang.String) [31]     53  aload_2 [a]     54  ldc <String "helloworld"> [19]     56  if_acmpne 63     59  iconst_1     60  goto 64     63  iconst_0     64  invokevirtual java.lang.StringBuilder.append(boolean) : java.lang.StringBuilder [34]     67  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [38]     70  invokevirtual java.io.PrintStream.println(java.lang.String) : void [42]     73  getstatic java.lang.System.out : java.io.PrintStream [21]     76  new java.lang.StringBuilder [27]     79  dup     80  ldc <String "a == x+y:"> [49]     82  invokespecial java.lang.StringBuilder(java.lang.String) [31]     85  aload_2 [a]     86  new java.lang.StringBuilder [27]     89  dup     90  aload_0 [x]     91  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [51]     94  invokespecial java.lang.StringBuilder(java.lang.String) [31]     97  aload_1 [y]     98  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [57]    101  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [38]    104  if_acmpne 111    107  iconst_1    108  goto 112    111  iconst_0    112  invokevirtual java.lang.StringBuilder.append(boolean) : java.lang.StringBuilder [34]    115  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [38]    118  invokevirtual java.io.PrintStream.println(java.lang.String) : void [42]    121  return

对于String常量,包括“hello”+“world”这种方式的的值(第54行),都被设置为常量。然而对于x+y这种方式,其实首先是创建了一个StringBuilder,然后把两个变量都加到StringBuilder内,再转换成String。此时,就形成了一个新的String对象了。equals方法也就不适用了。

三、Override覆盖
public class Parent {        public static String say() {          return "parent static say";      }        public String say2() {          return "parent say";      }  }    public class Child extends Parent {      public static String say() {          return "child static say";      }        public String say2() {          return "child say";      }  }  public class OverrideTest {        public static void main(String[] args) {          Parent p = new Child();          System.out.println(p.say());          System.out.println(p.say2());        }    }  

parent static say
child say

所谓静态方法,并不仅仅指该方法在所有实例中只有一份,同时也指该方法是“静态”加载的,即在编译期就已决定其行为。此处p的静态类型为Parent,所以它所调用的方法也在编译期和Parent的say()方法绑定:
  // Method descriptor #15 ([Ljava/lang/String;)V  // Stack: 2, Locals: 2  public static void main(java.lang.String[] args);     0  new com.ibm.oneteam.Child [16]     3  dup     4  invokespecial com.ibm.oneteam.Child() [18]     7  astore_1 [p]     8  getstatic java.lang.System.out : java.io.PrintStream [19]    11  invokestatic com.ibm.oneteam.Parent.say() : java.lang.String [25]    14  invokevirtual java.io.PrintStream.println(java.lang.String) : void [31]    17  getstatic java.lang.System.out : java.io.PrintStream [19]    20  aload_1 [p]    21  invokevirtual com.ibm.oneteam.Parent.say2() : java.lang.String [37]    24  invokevirtual java.io.PrintStream.println(java.lang.String) : void [31]    27  return


六、提前引用
public class ForwardReference {        static int first = test();      static int second = 2;        static int test() {          return second;      }        public static void main(String[] args) {          System.out.println("first = " + first);      }    }  

first = 0

这段代码有点诡异,但明白万变不离其宗,只要牢记静态方法&变量是“静态”加载的,即编译时就决定的即可。当然,对于静态变量的这种先定义后赋值的行为,还是需要小心:
public class com.ibm.oneteam.Main {    // Field descriptor #6 I  static int first;    // Field descriptor #6 I  static int second;    // Method descriptor #9 ()V  // Stack: 1, Locals: 0  static {};     0  invokestatic com.ibm.oneteam.Main.test() : int [11]     3  putstatic com.ibm.oneteam.Main.first : int [15]     6  iconst_2     7  putstatic com.ibm.oneteam.Main.second : int [17]    10  return      Line numbers:        [pc: 0, line: 5]        [pc: 6, line: 6]        [pc: 10, line: 3]    // Method descriptor #9 ()V  // Stack: 1, Locals: 1  public Main();    0  aload_0 [this]    1  invokespecial java.lang.Object() [22]    4  return      Line numbers:        [pc: 0, line: 3]      Local variable table:        [pc: 0, pc: 5] local: this index: 0 type: com.ibm.oneteam.Main    // Method descriptor #14 ()I  // Stack: 1, Locals: 0  static int test();    0  getstatic com.ibm.oneteam.Main.second : int [17]    3  ireturn      Line numbers:        [pc: 0, line: 9]

看这段代码也许更加直观点:
public class Main {    static int first = test();        static int second = 2;            static int test() {            return second;        }         static int third = 3;        public static void main(String[] args) {        System.out.println("first = " + first);    }}

编译后的代码:
// Compiled from Main.java (version 1.6 : 50.0, super bit)public class com.ibm.oneteam.Main {    // Field descriptor #6 I  static int first;    // Field descriptor #6 I  static int second;    // Field descriptor #6 I  static int third;    // Method descriptor #10 ()V  // Stack: 1, Locals: 0  static {};     0  invokestatic com.ibm.oneteam.Main.test() : int [12]     3  putstatic com.ibm.oneteam.Main.first : int [16]     6  iconst_2     7  putstatic com.ibm.oneteam.Main.second : int [18]    10  iconst_3    11  putstatic com.ibm.oneteam.Main.third : int [20]    14  return      Line numbers:        [pc: 0, line: 5]        [pc: 6, line: 6]        [pc: 10, line: 12]        [pc: 14, line: 3]    // Method descriptor #10 ()V  // Stack: 1, Locals: 1  public Main();    0  aload_0 [this]    1  invokespecial java.lang.Object() [25]    4  return      Line numbers:        [pc: 0, line: 3]      Local variable table:        [pc: 0, pc: 5] local: this index: 0 type: com.ibm.oneteam.Main    // Method descriptor #15 ()I  // Stack: 1, Locals: 0  static int test();    0  getstatic com.ibm.oneteam.Main.second : int [18]    3  ireturn      Line numbers:        [pc: 0, line: 9]    // Method descriptor #30 ([Ljava/lang/String;)V  // Stack: 4, Locals: 1  public static void main(java.lang.String[] args);     0  getstatic java.lang.System.out : java.io.PrintStream [31]     3  new java.lang.StringBuilder [37]     6  dup     7  ldc <String "first = "> [39]     9  invokespecial java.lang.StringBuilder(java.lang.String) [41]    12  getstatic com.ibm.oneteam.Main.first : int [16]    15  invokevirtual java.lang.StringBuilder.append(int) : java.lang.StringBuilder [44]    18  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [48]    21  invokevirtual java.io.PrintStream.println(java.lang.String) : void [52]    24  return      Line numbers:        [pc: 0, line: 15]        [pc: 24, line: 16]      Local variable table:        [pc: 0, pc: 25] local: args index: 0 type: java.lang.String[]}


七、对象引用
public class TestRef {        public static void main(String[] args) {          StringBuffer a = new StringBuffer("a");          StringBuffer b = new StringBuffer("b");          append(a, b);          System.out.println(a.toString() + "," + b.toString());          b = a;          System.out.println(a.toString() + "," + b.toString());      }        public static void append(StringBuffer a, StringBuffer b) {          a.append(b);          b = a;      }  }  

ab,b
ab,ab
这段代码就十分简单了,明白了引用拷贝就知道原因了。 1 楼 daly1987 2011-12-18   不错啊,加油

热点排行