dyerac  
          dyerac In Java
          公告

          日歷
          <2007年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678
          統(tǒng)計
          • 隨筆 - 36
          • 文章 - 10
          • 評論 - 94
          • 引用 - 0

          導航

          常用鏈接

          留言簿(5)

          隨筆分類(49)

          隨筆檔案(36)

          文章分類(11)

          文章檔案(10)

          相冊

          dyerac

          搜索

          •  

          積分與排名

          • 積分 - 79480
          • 排名 - 705

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

           
          要讓Java這個面向“對象”的世界正常運作,創(chuàng)建對象就是一項不可或缺的操作。

          public class NewMain {
              public static void main(String[] args) {
                  new Object();
              }
          }

          用javap反編譯上面的代碼,我們可以得到下面的指令,這里省去了javac暗中創(chuàng)建的構(gòu)造函數(shù)。

          public class NewMain extends java.lang.Object{
              ...
          public static void main(java.lang.String[]);
            Code:
             0:   new     #3; //class java/lang/Object
             3:   invokespecial   #8; //Method java/lang/Object."<init>":()V
             6:   return
          }

          從這段代碼中,我們可以清晰的看出創(chuàng)建對象(new)和調(diào)用構(gòu)造函數(shù)(invokespecial)兩個過程。關于這個問題,我在《對象的生命》中曾經(jīng)進行過討論。

          既然javac將一個new的動作被解釋為兩條指令,那在JVM的層面上,我們當然就可以將它們分開。下面是一段沒什么實際用途的代碼,只是證明這個觀點可行性。

          public class NewGenerator {
              public static void main(String[] args) throws Exception {
                  String className = "New";
                  ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
                  cw.visit(Opcodes.V1_2, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
                  Method m = Method.getMethod("void main (String[])");
                  GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, m, null, null, cw);
                  mg.newInstance(Type.getType(Object.class));
                  Label label = mg.newLabel();
                  mg.ifNonNull(label);
                  mg.mark(label);
                  mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
                  mg.push("new object is not null");
                  mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(java.lang.String)"));
                  mg.pop();
                  mg.returnValue();
                  mg.endMethod();
                  cw.visitEnd();

                  OutputStream os = null;
                  try {
                      os = new FileOutputStream(className + ".class");
                      os.write(cw.toByteArray());
                  } finally {
                      if (os != null) {
                          os.close();
                      }
                  }
              }
          }

          這段代碼生成的類是能夠運行的,有興趣的可以自己試一下。這段代碼的作用是new出一個對象之后,如果這個對象非空的話,就會產(chǎn)生一個輸出:
              new object is not null

          當然,如果嘗試用這個對象做一些其它的操作,會有錯誤等待著我們,因為這個對象并不是一個完整的對象。在JVM規(guī)范中有相關的解釋:new指令并不能完整創(chuàng)建出一個新的對象,直到對未初始化的對象調(diào)用了實例初始化方法才會完成實例的創(chuàng)建。這段代碼也正好符合《對象的生命》中的解釋,它只是負責做出申請內(nèi)存。當然,在JVM中,它的實際工作要略多一些,如果這個對象的類沒有加載,就會加載相應的類。
          posted on 2007-08-13 18:52 dyerac in java... 閱讀(386) 評論(0)  編輯  收藏 所屬分類: JavaSE
           
          Copyright © dyerac in java... Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 伊宁县| 衡东县| 广饶县| 青田县| 沈阳市| 潼南县| 定襄县| 黑龙江省| 兴山县| 名山县| 天峨县| 清丰县| 丰城市| 双辽市| 黄浦区| 高淳县| 抚顺县| 泸西县| 微山县| 鄂尔多斯市| 延寿县| 蒙山县| 江都市| 荃湾区| 台前县| 尉犁县| 卢湾区| 新蔡县| 房产| 正蓝旗| 瓮安县| 南涧| 怀远县| 荥经县| 达孜县| 金沙县| 贵南县| 红河县| 邵阳县| 诸城市| 文安县|