總網頁瀏覽量

2016年3月29日 星期二

[Java] instanceof 跟 static instanceof_static_test.java

instanceof_static_test.java

class A{
    static String name = "A";
    static String greeting(){
        return "Class A";
    }
}
public class instanceof_static_test extends A{
    static String name = "B";
    static String greeting(){
        return "Class B";
    }

    public static void main(String args[]){
        A a = new instanceof_static_test();
        System.out.println(a.name+", ");
        System.out.println(a.greeting());
       
        System.out.println();
       
        instanceof_static_test b = new instanceof_static_test();
        System.out.println(b.name+", ");
        System.out.println(b.greeting());       
    }
}

- - - - -
A,
Class A

B,
Class B
- - - - -

由上面程式碼來看,  一開始用A的觀點來建立instanceof_static_test物件,
而呼叫的name是類別層級的物件,
所以顯示出來的就會是A跟classA,
如果要顯示類別instanceof_static_test中的物件,
就要用instanceof_static_test來宣告.



2016年3月23日 星期三

[Java] SCJP 例題 221

Given:
7.   void waitForSignal(){
8.           Object obj = new Object();
9.            synchronized(Thread.currentThread()){
10.                   obj.wait();
11.                   obj.notify();
12.          }
13.  }

Which statement is true? [1]
  A. This code can throw an InterruptedException.
  B. This code can throw an IllegalMonitorStateException.
  C. This code can throw a TimeoutException after ten minutes.
  D. Reversing the order of obj.wait() and obj.notify() might cause
      this method to complete normally.
  E. A call to notify() or notifyAll() from another thread might cause
      this method to complete normally.
  F. This code does NOT compile unless "obj.wait()" is replaced with "((Thread) obj).wait()".


 網站解析

  IllegalMonitorStateException是說一個執行緒試圖在未取得物件lock時,
去對該物件進行等待(wait)或通知(notify)的動作,會產生的一個不合法的監控狀態例外。

         正確的程式寫法應如下:
                   synchronized(obj) {
                     }
         取行obj的lock後,方能對obj進行wait或notify。


[1] 192.192.246.169/~wells/wiki/index.php/SCJP_1.6版考題_221

對於這種選項多又沒講要答幾個的題目真的很難判斷,
這題我選AD。
因為我以為wait()沒在try-catch()理面的問題比較大,
原來包在他外面的 synchronized()更大,又一次失物。

同步synchronized()有三種,沒記錯的話一種式放置在方法宣告中,
另外兩種式synchronized(o)和synchronized(class)。

[Java] SCJP 例題 127

Given:
1. public class Donkey2{
2.   public static void main(Stnng[] args){
3.     boolean assertsOn = true;
4.     assert(assertsOn): assertsOn = true;
5.     if(assertsOn){
6.       System.out.println("assert is on");
7.     }
8.   }
9. }
 

If class Donkey2 is invoked twice,
the first time without assertions enabled,
and the second time with assertions enabled,
what are the results?[1]
  A. no output
  B. no output assert is on
  C. assert is on
  D. no output , An Assertion Error is thrown.
  E. assert is on , An AssertionError is thrown.
 
 
這題,真難懂...
看了解說
即使assert作用,4行也不會發生assertion error, assertOn是false才會發生assertion error 
也看不懂
 
 
另一個[2]解說  

題意為:第一次執行把assertions設為運作,第二次設為不運作。Assert 是一個在除錯階段時才會使用到的關鍵字,他可以藉由編譯器設定來開關這個功能
assert的判別式成立,則不會觸發任何事情;如果不成立,則會觸AssertionError,或是冒號後面的程序
要注意的是:AssertionError或是冒號後面的程序並不會馬上被觸發,如果把assertsOn初始直設為false,則不會印出任何東西,因為執行到if判別式時,assertsOn的值還依然是false
assert關鍵字是提供工程師在除錯階段使用,工程師可以將此關鍵字加在某個片段中測試某個數值是否有如預期。assert並不能取代if 來使用

好像懂了什麼, 題目一開始的意思地一次設為運作就是第三行 assertsOn =true 時候,
第二次不運作又表示 assertsOn = false所以第五行判斷後當然不會執行裡面敘述阿. = =
 
原來還可以這樣出題阿... 
 
 
[1] http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_127 
[2] http://yaya741228.pixnet.net/blog/post/87293752-scjp-6.0%E8%80%83%E5%8F%A4%E9%A1%8C%E8%A7%A3%E6%9E%90-%28126~130%29 

2016年3月22日 星期二

[Java] SCJP 例題 032/例題 034 is-a/has-a

例題 032 

1. class Mammal{}
2.
3. class Raccoon extends Mammal {
4. Mammal m = new Mammal();
5. }
6.
7. class BabyRaccoon extends Mammal{}


Which four statements are true? (Choose four.)[1]

  A. Raccoon is-a Mammal.
  B. Raccoon has-a Mammal.
  C. BabyRaccoon is-a Mammal.
  D. BabyRaccoon is-a Raccoon.
  E. BabyRaccoon has-a Mammal.
  F. BabyRaccoon is-a BabyRaccoon.
 
[1] http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_032 
 
 
這題我選 ABC (E),
看來繼承之後附類別的物件不能算式子類別的, not has-a, 
而自己也可以是自己, 雖然很怪.

之後看到在來更新一下XD
 
- - - - - - - - - - 
 
例題 034 
 
 
Which four statements are true? (Choose four.)[2]
   A. Has-a relationships should never be encapsulated.
   B. Has-a relationships should be implemented using inheritance.
   C. Has-a relationships can be implemented using instance variables.
   D. Is-a relationships can be implemented using the extends keyword.
   E. Is-a relationships can be implemented using the implements keyword.
   F. The relationship between Movie and Actress is an example of an is-a relationship.
   G. An array or a collection can be used to implement a one-to-many has-a relationship. 
 
網站的中文說明
 
那四個敘述是正確的?
  A. Has-a 關係應該永遠不能被封裝
  B. Has-a 關係應該以繼承的方式實作
  C. Has-a 關係可以用物件變數的方式被實現出來
  D. Is-a關係可用extends關鍵字實現出來
  E. Is-a關係可用implements關鍵字實現出來
  F. 電影和女演員間的關係是一個Is-a關係的例子
  G. 一個陣列或一個集合可以被用來實作一對多的has-a關係 

[2] http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_034

A. Has-a 可以被封裝.
B. Has-a 不可用繼承方式實做.
C. Has-a 可以用實做變數來實現.
D. Is-a  可以用繼承來實現.
E. Is-a  可以用implements實現.
F. 電影和女演員的關係是Has-a的關係.
G. 陣列和集合可被一對多的Has-a實現.

[Java] SCJP 例題 020/例題 023/例題 024

例題 020 

A team of programmers is reviewing a proposed API for a new utility class.
   一組程式設計師正在檢視一個新工具類別的程式設計介面(API)

After some discussion經過一些討論之後,
 
they realize that they can reduce the number of methods in the API without losing any functionality.
   他們了解到,在沒有喪失任何功能情況下,可以降低這組API的方法數量。


If they implement the new design, which two OO principles will they be promoting?
   如果他們實作這個設計(想法),他們必須遵循那二個OO的原則?[1]

   A. Looser coupling
   B. Tighter coupling
   C. Lower cohesion
   D. Higher cohesion  
   E. Weaker encapsulation
   F. Stronger encapsulation
 
 
[1] http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_020 

這題非常非常陌生, 感覺沒看過這種敘述,
雖然以前老師有提過, 但是只要一個禮拜不看就忘了這回事.
 
這題自己寫的時候還是記得把中文蓋著吧, 感覺考是應該沒有. 

依照網站上的解析
 
 Coupling:模組間的耦合度,愈低愈好,亦即模組獨立性要高
 Cohesion:模組的內聚力,表示模組內的成員都是為模組單一功能的設計而共同存在

 一般來說,設計系統,分割功能模組必須模組間不能互相牽連,以介面做為模組間溝通的工具,當一個模組修改時,另一個模組不致於也要跟著修改。
 而一個功能模組僅實現單一功能,不會一個模組要同時實現多個功能使得模組內變得超複雜。 

好像把目標放在Coupling和Cohesion兩個的解釋上.
Looser coupling 鬆散耦合 
Lower cohesion  低凝聚力
 
 
 
- - - - - - - - - - - 
例題 023 
 
A company has a business application that provides its users with many different reports: receivables reports, 
payables reports, revenue projects, and so on.
  某家公司有一個商用程式,提供它的使用者許多報表製作,像是…

The company has just purchased some new, state-of-the-art,wireless printers, 
and a programmer has been assigned the task of enhancing all of the reports to use 
not only the company‘s old  printers, but the new wireless printers as well. 
  這家公司剛好採購了一些新的、完美的無線印表機,一個程式設計師被指定一個工作-加強報表功能,
  使得原本的報表功能不只可以使用舊的印表機,也能使用這些新式的印表機!

When the programmer starts looking into the application, 
the programmer discovers that because of the design of the application, 
it is necessary to make changes to each report to support the new printers. 


Which two design concepts most likely explain the situation? (Choose two.)

   A. Inheritance
   B. Low cohesion
   C. Tight coupling
   D. High cohesion
   E. Loose coupling
   F. Object immutablility 


由上面兩題看, 要把功能緊緊綁在一起, 讓新舊並行,
就需要Low cohesion和Tight coupling,  (023)
而開發新的功能要與舊的有差異, 不要讓重覆工能太多,
就需要Looser coupling 和 Lower cohesion . (020)
 
好項需要去看一下影片, 有看到有人說要老師提供. ㄏㄏ 
 
- - - - - - - - - - 
 例題 024 
 
A company that makes Computer Assisted Design(CAD) software has, 
within its application some utility classes that are used to perform 3D rendering tasks. 
  有一些工具類別被使用來進行3D著色工作

The company's chief scientist has just improved the performance of one of 
the utility classes' key rendering  algorithms, and has assigned a programmer to replace the old algorithm 
with the new algorithm.

When the programmer begins researching the utility classes, 
she is happy to discover that the algorithm to be replaced exists in only one class.
The programmer reviews that class‘s API,
and replaces the old algorithm with the new algorithm, 
being careful that her changes adhere strictly to the class’s API.

Once testing has begun, 
the programmer discovers that other classes that use the class she changed are no longer working properly. 
  (她發現到…她做了一些改變之後,一些使用到她改變的類別的其他類別再也不能正常地運作…)
   

What design flaw is most likely the cause of there new bugs?
  A. Inheritance
  B. Tight coupling
  C. Low cohesion
  D. High cohesion
  E. Loose coupling
  F. Object immutablility
 
感覺上是因為耦合度太高導致功能重疊就修改到了 

[Java] SCJP 例題 119

Given:
11. public static void main(String[] args){
12.   String str = "null";
13.   if (str == null) {
14.     System.out.println("null");
15.   }else (str.length() == 0) {
16.     System.outprintln("zero");
17.   }else{
18.     System.out.println("some");
19.   }
20. }


What is the result?[1]
  A. null
  B. zero
  C. some
  D. Compilation fails.
  E. An exception is thrown at runtime.
 
少了一個if.
 

[1] http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_119

這不是重點啦XD

如果成是正確的, 有加上if呢?!
答案會是some, 因為String理面有字串"null", str.length() = 4.
 
除非你將String str="", 那答案才會是zero.
 
好像不會有答案跳到null, 因為str如果沒給値就放置判斷式中,
這個String沒初始化, 在編譯時就會被擋下來. 

ex_119_string_null.java:4: error: variable s might not have been initialized
                if(str == null)
                   ^
1 error


- - - - -
public class ex_119_string_null{
 public static void main(String args[]){
  String str ="";
  if(str == null)
   System.out.println("null");
  else if(str.length()==0)
   System.out.println("zero");
  else
   System.out.println("else: "+str+" "+str.length());
 }
}

[Java] SCJP 題庫 008

1. public class Spock{
2.   public static void main(String[] args){
3.     Long tail = 2000L;
4.     Long distance = 1999L;
5.     Long story = 1000L;
6.     if((tail>distance) ^ ((story*2)==tail))
7.     System.out.print("1");
8.     if((distance+1 != tail) ^ ((story*2)==distance))
9.     System.out.print("2");
10.   }
11. } 


What is the result?[1]

   A. 1
   B. 2
   C. 12
   D. Compilation fails.
   E. No output is produced.
   F. An exception is thrown at runtime.
 
 這個在網站上雖然沒有講解, 但是以我的理解,
因為if的判斷是會以布林運算式判斷, 但是判斷前先執行() 內的運算,
而!=這種等號都會以整數int型態來運算,對於long型態而言,
小數點後的値就算1L-1L也可能會等於0.000000***這種情況出現,
所以第六行(tail>distance) => (2000L>1999L) -> true,
((story*2)==tail) => ((1000L*2)==2000L) -> false,
而true ^ false -> false 

  
[1] http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_008
 
  
針對邏輯運算子給自己一點測試吧, 在猛虎的1-9-5(p1-45).

運算子  說明    範例  類別
 &  AND  a&b  雙元
 |   OR   a|b  雙元 
 !  NOT   !a   單元

short-circuit Operator
 && AND  a&&b 雙元
 ||  OR   a||b 單元

而沒短路的情況之下,判斷是在做完左邊運算後仍會執行右邊運算。
在短路情況下,則是在左邊運算式為false情況下,才會執行右運算。

- - - - - 
ex_008_operator.java 
public class ex_008_operator{
 public static void main(String args[]){
  int a = 1, b = 2;
  System.out.println((a<b)&&(a>0)); //t && t  -> t
  System.out.println((a<b)&(a>0));  //t &  t  -> t
  System.out.println((a>b)||(a<0)); //f || f  -> f
  System.out.println((a>b)|(a<0));  //f |  f  -> f  
  System.out.println(!(a>b));       //!f      -> t
  
  System.out.println(a);            // (1) 
  if((a<b)|(++a>0))             
   System.out.println(a--);  // (2) 
  System.out.println(a);            // (1)
  
  System.out.println(a&b); //0001 & 0010 -> 0000 (0)
  System.out.println(b&b); //0010 & 0010 -> 0000 (2)
  System.out.println(a|b); //0001 | 0010 -> 0011 (3)
  System.out.println(b|b); //0010 | 0010 -> 0010 (2)
  System.out.println(a^a); //0001 ^ 0001 -> 0000 (0)
  System.out.println(a^b); //0001 ^ 0010 -> 0011 (3)
  System.out.println(a^7); //0001 ^ 0111 -> 0110 (6)
 }
}

前面部分為猛虎的範例, 後面是我的測試,
其實主要在" ^ "啦, 因為這啥全忘了,
由側式可以看出來是 XOR, 相異才為1, 相同為0.

另外, 在if裡面運用運算元也是可以改値的.












2016年3月21日 星期一

[Java] SCJP 題庫 003

1. public class Test{
2.   public static void main(String[] args){
3.      int x = 5;
4.      boolean b1 = true;
5.      boolean b2 = false;
6.
7.      if((x==4) && !b2)
8.      System.out.print("1 ");
9.      System.out.print("2 ");
10.    if ((b2=true) && b1)
11.    System.out.print("3 ");
12.  }
13.}


What is the result?

   A. 2
   B. 3
   C. 1 2
   D. 2 3
   E. 1 2 3
   F. Compilation fails.
   G. An exception is thrown at runtime.
 
 其實這題我種是卡在if判斷是中的運算元裡面,
&&是短路, 表示當前敘述不成立, 就表示後敘述仍然會執行,
但是這是一個AND的邏輯運算, 所以false && true => false.
所以這裡的第8行並不會執行.
 
在來第10行的b2 = true, 這裡放了一個 = 的指派運算子,
只要編譯正確就會給予預設的true値,
所以第10行, true && true => true

[Java] SCJP 題庫 001


Given: 

1. public class Threads4{ 
2.          public static void main(String[] args){ 
3.                   new Threads4.go(); 
4.           } 
5.          public void go(){ 
6.                  Runnable r = new Runnable(){ 
7.                          public void run(){ 
8.                                   System.out.print("foo");  
9.                          } 
10.                }; 
11.               Thread t = new Thread(r); 
12.               t.start(); 
13.               t.start(); 
14.         } 
15.  } 

 
What is the result? 
   A. Compilation fails. 
   B. An exception is thrown at runtime. 
   C. The code executes normally and prints "foo"; 
   D. The code executes normally, but nothing is printed.
 
只是吹毛求疵了一下,
這個程是本身第3行應該要改成 
new Threads4().go();
 
不然會有編譯錯誤 
Threads4.java:12: error: cannot find symbol
                new Threads4.good();
                                       ^
  symbol:   class good
  location: class Threads4 
1 error


而以上都只是個人的吹毛求疵, 不是題目重點, 不然答案就是A了.

在程式中出現兩個 t.start();

編譯正確但是執行錯誤

fooException in thread "main"
java.lang.IllegalThreadStateException
        at java.lang.Thread.start(Thread.java:705)
        at ex_004_thread_start.go(ex_004_thread_start.java:13)
        at ex_004_thread_start.main(ex_004_thread_start.java:3)
 
 
陳富國網路資源 
http://192.192.246.169/~wells/wiki/index.php/SCJP_1.6%E7%89%88%E8%80%83%E9%A1%8C_001
答案給了E
說明為 一個執行緒只能啟動一次 (t.start()只能下一次),執行緒是物件,物件相關的動作發生問題是在執行時期產生例外,而不是編譯的錯誤。 
 
而不是跟B一樣嗎, 這部分可能就要考慮到  
https://www.javaworld.com.tw/jute/post/view?bid=17&id=276985

有提到因為題目錯誤, 不想使讀者誤解, 所以才另外寫下答案.
(這是我個人的歸納拉 XD)

[Java] while 哎呀

其實是看到 SCJP題庫的這題,
在想說記一下的.

Given:
    int x = 0;
    int y = 10;
    while (x < 5) {
        y--;
        ++x;
    } ;
    System.out.print(x + "," + y);


What is the result?
A. 5,6
B. 5,5
C. 6,5
D. 6,6


其實沒啥, 答案推一下就知道是 B

1. 0 0
2. 9 1
3. 8 2
4. 7 3
5. 6 4
6. 5 5
在進入迴圈就判斷為false, 跳出 

只是while(){}";"多了這個分號,
原以為while只能執行一次, 結果沒差.

試了一下連for-loop都可以, 好吧.


whiledot.java

public class whiledot{
    public static void main(String args[]){
        int x =0;
        while(x<10){
            System.out.println("x: "+x++);
        }
       
        for(int i = 0 ; i < 10 ; i++){
            System.out.println("i: "+i);
        };
    }
}


- - - - - 
x: 0
x: 1
x: 2
x: 3
x: 4
x: 5
x: 6
x: 7
x: 8
x: 9
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9

2016年3月16日 星期三

bytecode 取類別取方法

sandmark.program.Class aclass = (sandmark.program.Class) classes.next();
得到classfile
org.apache.bcel.generic.ConstantPoolGen cp = aclass.getConstantPool();
得到classfile的constantpool
String ID = getConfigProperties().getProperty("SWM_ConstantStrin_Ident");
像是給ID一個屬性(?
 cp.addString(ID+"="+(你要加上的字串));


2016年3月14日 星期一

[Java] Constantpool 數量計算

sandmark.program.Class a = (sandmark.program.Class) classes.next();
org.apache.bcel.generic.ConstantPoolGen b = a.getConstantPool();
int constantpoolcount = b.getSize();

4.4. The Constant Pool

4.4. The Constant Pool

JVM的指令不是在run time執行。

 所有的constant_pool Table形式一般像是:
  cp_info {
   u1 tag;
   u2 info[];
  }

  在 constant_pool table 中的列表都開始於 1-byte tag 中顯示cp_info的種類。而info的內容種類與tag的值對應。每個tag byte都伴隨2到更多的byte資訊。

[零] The class File Format

Chapter 4. The class File Format

  每個class檔都包含著定義單一class檔或interface。

  一個class檔,組成由 8-bit Byte的stream。全部 16-bit、32-bit、64-bit的數量建構成2、4、8連續的8-bit bytes。多數量(Multibyte)的檔案項目通常儲存在bit-endian order, where the high bytes come first。在Java SE平臺中,這些型態都是由幾個介面提供,java.io.DataInputjava.io.DataOutput,以及class提供,java.io.DataInputStreamjava.io.DataInputStream.

   現在所講的,class 檔案形式: 類別(type)u1, u2, u4,個別是無號(unsigned)1, 2, 4 byte。在Java SE平台上,這些類別讀取的method是由readUnsignedBytereadUnsignedShortreadInt和介面java.io.DataInput。


  目前所講的class file形式上使用pseudostructures編寫 a C-like structure notation(?)。避免class中的filed和class中的interface。

  Tables,包含了0到更大的的可變大小項目,以使用在多個class file structures。雖然使用了C-like array syntat來對應talble的項目,是實上,table是多變的stream結構,也代表著不可能轉換一個table index 到 byte offset。  (?)

  這裡的Data structure是個array陣列,包含了0到更多的大小項目,可以有類似array的編列。
  
  相關於ASCII字元似的說明,表示Unicode code point對應ASCII character。


[1] https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html

2016年3月10日 星期四

[java] Constant pool

  JVM在每種類型(type)加載時, 都提供(store)一個常量池(constant pool)記錄。常量池是一個有序(ordered)的集合,集合內存放類型所使用的常量,包含string、integer、floating point constants和 symbolic references to types、fields、and methods。

  常數池通過索引參照。因為常量池儲存了宣告(symbolic references)引用之型態(type),參數(field)、方法所使用到之型態(methods used by a type),動態鍊結的方式在java program裡作控制.[2]

  一般而言,constant pool都包含魔術數字(Magic Number,[3])和版本編號(version numbers),像是在JVM介紹裡, constant pool包含檔案中常數(constant)相關(associate)的類別或介面,這些常數就像文字字串(literal string)般顯示,將final variable、class names、method name存在池中。常量池一個有組織entries列表,在list這些entries列表的數量,constant_cool.count,而列表(list)的,precedes the actual list。


  constant_pool常量池中許多entries都會指到(refer to)其他entries,許多條目(items)也是一樣,在整個class file檔案中,常量池都有一個編號給與對應到位於哪個constant_pool的位置,在list中的第一項索引為1,以此類推。雖然constant_pool列表中沒有索引為0的入口,
但是仍然會進算於constant_pool_count裡面。
假如 constant_pool含有十四項entries(#1-#14),在constant_pool_count則還是15。 (?)

  constant pool 進去後, 就會用 one-byte tag作為開頭, 這個tag包含constant 的類別(type),
一旦JVM開始執行翻譯這tag, 就知道此tag後的常量類型是什麼


able 6-3. Constant pool tags
Entry Type           Tag Value    Description
CONSTANT_Utf8          1     A UTF-8 encoded Unicode string
CONSTANT_Integer      3     An int literal value
CONSTANT_Float         4     A float literal value
CONSTANT_Long         5     A long literal value
CONSTANT_Double      6     A double literal value
CONSTANT_Class        7     A symbolic reference to a class or interface
CONSTANT_String        8     A String literal value
CONSTANT_Fieldref   9     A symbolic reference to a field
CONSTANT_Methodref    10     A symbolic reference to a method declared in a class
CONSTANT_InterfaceMethodref     11     A symbolic reference to a method declared in an                    interface
CONSTANT_NameAndTyp  12     Part of a symbolic reference to a field or method

舉例來講 
#11=Utf8  main

#11 代表索引值,UTF8 是tag 代表,接在後方的constant其類別。

每個entry type都和一個tag value對應,這些tag的名字都會在後面加上

The constant pool plays an important role in the dynamic linking of Java programs.(簡單免翻)
除了 literal constant values(字面常量,值接量),也包含三中符號引用:
1. fully qualified names of classes and interfaces
2. field names and descriptors
3. method names and descriptors

A field is an instance or class variable of the class or interface.
A field descriptor is a string that indicates the fields type. 
A method descriptor is a string that indicates the methods return type and the number, order, and types of its parameters.

The constant pools fully qualified names and method and field descriptors are used at run time to link code in this class or interface with code and data in other classes and interfaces.


class file 不包含內部的 memory layout原件,就是記憶體分配布局之信息,所以classes、fieldes、method不能值接參考到class file 中的bytecode。

JVM在run time時,從constant pool中給予其對映的參考(reference),就值接解決要使用address 的參照。比如果,在bytecode的指令碼索引參考到常量池之索引給予JVM執行。


- - - - -
Constant pool是個有順序性的cp_info列表,cp_info列表中的tag,是個unsigned byte,
表示的variety和format。其中,cp_info有十一個值,每個都描述。

Type  Name  Count
  u1          tag               1
  u1          info            depends on tag valuse

HellowWorld.java

public class HellowWorld{
  public static void main(String args[]){
    System.out.println("HAAAAA"); 
  }
}

 
Constant pool:
 #1 = Methodref     #6.#15         // java/lang/Object."<init>":()V
 #2 = Fieldref           #16.#17        // java/lang/System.out:Ljava/io/PrintStream;
 #3 = String             #18            // HAAAAA
 #4 = Methodref    #19.#20        // java/io/PrintStream.println:(Ljava/lang/String;)V
 #5 = Class              #21            // HellowWorld
 #6 = Class              #22            // java/lang/Object
 #7 = Utf8               <init>
 #8 = Utf8               ()V
 #9 = Utf8               Code
#10 = Utf8               LineNumberTable
#11 = Utf8               main
#12 = Utf8               ([Ljava/lang/String;)V
#13 = Utf8               SourceFile
#14 = Utf8               HellowWorld.java
#15 = NameAndType        #7:#8          // "<init>":()V
#16 = Class              #23            // java/lang/System
#17 = NameAndType        #24:#25        // out:Ljava/io/PrintStream;
#18 = Utf8                HAAAAA
#19 = Class              #26            // java/io/PrintStream
#20 = NameAndType        #27:#28        // println:(Ljava/lang/String;)V
#21 = Utf8               HellowWorld
#22 = Utf8               java/lang/Object
#23 = Utf8               java/lang/System
#24 = Utf8               out
#25 = Utf8               Ljava/io/PrintStream;
#26 = Utf8               java/io/PrintStream
#27 = Utf8               println
#28 = Utf8               (Ljava/lang/String;)V


 
The resulting bytecode 
public HellowWorld();
  descriptor: ()V
  flags: ACC_PUBLIC
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
    LineNumberTable:
      line 1: 0
public static void main(java.lang.String[]);
  descriptor: ([Ljava/lang/String;)V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=2, locals=1, args_size=1
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String  HAAAAA
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
    LineNumberTable:
      line 3: 0
      line 4: 8



由這個簡單的程式中理解bytecode.[1]

有兩個method在bytecode裡面, 一個是HellowWorld, 另一個是 main,
但是哪個是程式第一個執行的method? 
我們在 HellowWorld.java只定義了一個method, 
不是只有main怎麼現在bytecode中又有兩個method呢?
程式的第一個method, 是HellowWorld, 
這個method預設建構子(default constructors)出來是由程式編譯時編譯器補上的, 
如你所期待的那樣, 這個預設建構子是public且沒有參數(arguments)的.
所以, 他們的產生是由編譯器(Compiler)執行並直接放置(put)在bytecode的.

現在看到bytecode部分, 觀察一下method內的地方.
開始的預設建構子在bytecode這裡, 開始的第一行:

0: aload_0

開始值為 0(0:) 這個是一開始執行method所表示的偏移量(offset).
表示這個為首的指令instruction標記他是 0, 這就是為什麼要在這裡討論他,
直接看這個值非常不合邏輯. 而剩下的其他指令是operator稱為opcode.
 - - - - - 
應該是這個吧( ?!

Code: 
  0: aload_0 
  1: invokespecial #1; //Method java/lang/Object."":()V 
  4: return
- - - - -

從第一行中, 我們將會把 local variable table的值放(push) 到stack.
在我們的這個例子裡, 我們確實只會放了一個參考(reference)就this, 
但他是不存在的指令instrucation.

所以我們希望下一行指令做啥??

  1: invokespecial #1; //Method java/lang/Object."":()V 

為什麼我們要知道建構子?
為什麼建構子是第一件做的事?
他執行(invokes)父類別(parent class) 建構子.

這只是, 這行不只做了這件事情阿-他執行了父類別的建構子(這個例子中,物件). 
那為什麼是跟 #1 ? 這就是一個 constant table 的 index.
index #1 參考到 建構子的物件.

最後, 最下面那行, 回傳我們的建構子.

這雖然不是很屌的method, 但是確可以幫助我們一路了解到從頭到尾的bytecode.
make head or tail of bytecode 這英文好玩.

0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;

這行的opcode getstatic. 
你可能就會猜, 這個opcode拿到一個static field(在這個例子中, System.out)
和push他到 operand stack中. 當你可能又在猜, #2 就牽涉到field到我們的constant table中.


3: ldc #3; //String HAAAAA
 

這行的ldc,載入(load)這個參數到operand stack中, 從這點來看我們載入的不管是不是

哪一種參數都會在constant table的編號 #3 中 . 這行就是我們的String, "HAAAAA"

 

接下來,

 
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

 
這行執行了我們物件System.out中的println的method, 這個過程的執行是做pop兩個
operands移出stack和執行method, 之後我們的method就會結束, 然後return.

 
 
 
[1] http://www.javaranch.com/journal/200408/Journal200408.jsp#a1 
[2] http://denverj.iteye.com/blog/1210979 
[3] http://openhome.cc/Gossip/JavaEssence/SourceTarget.html

2016年3月9日 星期三

[日常] 同樣發音, 容易混淆的好像的字

給予 給與[1]

給與:拿東西給別人。如:「給與」獎狀、「給與」救濟。同「給予」。
給予:給人家東西。如:「給予」獎勵。予亦作「與」。

其實「給予」與「給與」意思是一樣的。






檢查 檢察 [3]
將一般的檢查寫成「查」 ,特別仔細的檢查寫成「察」 。

權利 權力[4]
權利(right)是指法律所賦予人民的私權
權力(power)則是一種政治上之力量,是由國家所享有,用以確保人民之「權利」。