JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java SE 討論區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
作者 繼承函數初始化的問題
limhi





發文: 17
積分: 0
於 2019-04-17 12:13 user profilesend a private message to usersend email to limhireply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
大家好:
最近遇到一個很奇怪的BUG,追蹤到最後,發現了一個我解釋不出來的問題
用簡化過的程式碼表達吧~

MyParent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyParent {
  public MyParent(JSONObject json) {
    setup(json);
  }
 
  public void print() {
    print_imp();
  }
 
  protected void setup(JSONObject json) {
    System.out.println("in MyParent, call setup()");
    throw new RuntimeException("需要實作");
  }
 
  protected void print_imp() {
    System.out.println("in MyParent, call print_imp()");
    throw new RuntimeException("需要實作");
  }
}


MyChild
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MyChild extends MyParent {
  private Integer height = null;
  private Integer age = 0; 
  private Integer weight;  //<==沒給值
 
  public MyChild(JSONObject json) {
    super(json);
  }
 
  protected void setup(JSONObject json) {
    height = json.getInteger("height");
    age = json.getInteger("age");
    weight = json.getInteger("weight");
    System.out.println("in MyChild call setup(), height = " + height);
    System.out.println("in MyChild call setup(), age = " + age);
    System.out.println("in MyChild call setup(), weight = " + weight);
  }
 
  protected void print_imp() {
    System.out.println("in MyChild call print_imp(), height = " + height);
    System.out.println("in MyChild call print_imp(), age = " + age);
    System.out.println("in MyChild call print_imp(), weight = " + weight);
  }
}


MyMain
1
2
3
4
5
6
7
8
9
10
public class MyMain {
  public static void main(String[] args) {
    JSONObject json = new JSONObject();
    json.put("height", 180);
    json.put("age", 18);
    json.put("weight", 60);
    MyParent instance = new MyChild(json);
    instance.print();
  }
}


這樣設計的目地,只是要求配合實作的同事們,要自行實作setup和print_imp
但是在執行結果如下:
1
2
3
4
5
6
7
8
in MyChild, call setup()
in MyChild call setup(), height = 180
in MyChild call setup(), age = 18
in MyChild call setup(), weight = 60
 
in MyChild call print_imp(), height = null
in MyChild call print_imp(), age = 0
in MyChild call print_imp(), weight = 60


除了weight被正確初始化,其他二個變數都沒按照希望的方式初始化
追蹤到最後,確定是MyChild中宣告變數的方式不同所導致
1
2
3
  private Integer height = null;
  private Integer age = 0; 
  private Integer weight;  //<==沒給值


想請教各位前輩,明明就都是在MyChild中的同一個實例所包含的函數在執行
為何有不同結果??


reply to postreply to post
作者 Re:繼承函數初始化的問題 [Re:limhi]
Landgray





發文: 78
積分: 0
於 2019-04-17 20:57 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
就初始化的順序問題

建構子跑完才跑其它給直等式的概念


reply to postreply to post
作者 Re:繼承函數初始化的問題 [Re:Landgray]
roytsang





發文: 618
積分: 1
於 2019-04-18 09:40 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
小弟不明白,可否詳細講解一下呢?

reply to postreply to post
作者 Re:繼承函數初始化的問題 [Re:roytsang]
Landgray





發文: 78
積分: 0
於 2019-04-18 17:57 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
private Integer height = null;

改成

private Integer height = initHeight();
private Integer initHeight(){
   System.out.println("initHeight");
  return null;
}

跑下去就會看到
method initHeight()會在建構子跑完之後才跑

更詳細的順序啥的 就要翻文件了


reply to postreply to post
作者 Re:繼承函數初始化的問題 [Re:Landgray]
limhi





發文: 17
積分: 0
於 2019-04-22 11:25 user profilesend a private message to usersend email to limhireply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
確實如同各位前輩所說
是JAVA自動將宣告時有給值的變數,自動放到建構子的最後面

實務上,避開這個問題的方式也蠻簡單的
( 因為無法保證每個配合的同事都有各位前輩的功力啊 ~ )

在主控程式中建立實體後,先呼叫setup(),再呼叫print()即可
( 我發現問題的當天就知其然不知其所以然的改好了 )

現在我終於知道為什麼了

謝謝大家!


reply to postreply to post
» JWorld@TW »  Java SE 討論區

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8