日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 对象初始化过程

發布時間:2024/4/15 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 对象初始化过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

例子里總共測試了靜態代碼塊,普通代碼塊,靜態成員變量,普通成員 變量,構造器。分別在基類和派生類里各有一套。

public class ClassLog {private static final String TAG = "ClassLog";public static String baseFieldInit() {Loger.i(TAG, "baseFieldInit");return "";}public static String baseStaticFieldInit() {Loger.i(TAG, "baseStaticFieldInit");return "";}public static String childFieldInit() {Loger.i(TAG, "childFieldInit");return "";}public static String childStaticFieldInit() {Loger.i(TAG, "childStaticFieldInit");return "";} } public class ClassBase {private static final String TAG = "ClassBase";static {System.out.println("Base Static Block 1");}private static String BASE_STATIC_VALUE = ClassLog.baseStaticFieldInit();static {Loger.i(TAG, "Base Static Block 2");}{Loger.i(TAG, "Base Normal Block 1");}private String baseNormalValue = ClassLog.baseFieldInit();{Loger.i(TAG, "Base Normal Block 2");}public ClassBase() {Loger.i(TAG, "Base Class Constructor");} }
public class ClassChild extends ClassBase {private static final String TAG = "ClassChild";static {Loger.i(TAG, "Child Static Block 1");}private static String CHILD_STATIC_VALUE = ClassLog.childStaticFieldInit();static {Loger.i(TAG, "Child Static Block 2");}{Loger.i(TAG, "Child Normal Block 1");}private String childNormalValue = ClassLog.childFieldInit();{Loger.i(TAG, "Child Normal Block 2");}public ClassChild() {Loger.i(TAG, "Child Class Constructor");} }

創建一個ClassChild類的對象:

ClassChild tChild = new ClassChild();


Log 如下:




結果證明:

對象在class文件加載完畢,以及為各成員在方法區開辟好內存空間后,就開始了所謂“初始化”的過程:

1.基類靜態代碼塊、基類靜態成員字段(并列優先級,按代碼中出現的先后順序)(只有第一次加載類時執行);

2.派生類靜態代碼塊、基類靜態成員字段(并列優先級,按代碼中出現的先后順序)(只有第一次加載類時執行);

3.基類普通代碼塊、基類普通成員字段(并列優先級,按代碼中出現的先后順序);

4.基類構造函數;

5.派生類普通代碼塊、基類普通成員字段(并列優先級,按代碼中出現的先后順序);

6.派生類構造函數;


注意: 第1、第2步驟的靜態過程,只在這個類第一次被加載的時候才會運行。

再創建一個ClassChild類的對象:

ClassChild tChild = new ClassChild();



第二次創建只執行3、4、5,6步。


From:https://www.zhihu.com/question/49196023



Java Object Initialization Order - Know your JLS!

Recently I came across an interesting problem whose solution eluded me at first glance. Consider these three classes:
package com.ds.test;public class Upper {String upperString;public Upper() {Initializer.initialize(this);} } package com.ds.test;public class Lower extends Upper {String lowerString = null;public Lower() {super();System.out.println("Upper: " + upperString);System.out.println("Lower: " + lowerString);}public static void main(final String[] args) {new Lower();} } package com.ds.test; public class Initializer {static void initialize(final Upper anUpper) {if (anUpper instanceof Lower) {Lower lower = (Lower) anUpper;lower.lowerString = "lowerInited";}anUpper.upperString = "upperInited";} } What output is to be expected from running the?Lower?class?

In this very reduced example it is much easier to get a view of the whole situation - in reality where this occurred there was a lot more code to distract one's attention...
Anyway, this is what the output looks like:
Upper: upperInited Lower: null; While the little example uses Strings, the real code of?Initializer?had a delegate object registered with the equivalent of the?Lower?class - at least that was the intention. For some reason however did this not work when running the application. Instead, the default path was taken - the one for the delegate object being not set (null).
Now, change the code of?Lower?slightly:
package com.ds.test;public class Lower extends Upper {String lowerString;public Lower() {super();System.out.println("Upper: " + upperString);System.out.println("Lower: " + lowerString);}public static void main(final String[] args) {new Lower();} } The output is now:
Upper: upperInited Lower: lowerInited Notice the difference in the code?
Yes, the?lowerString?field is no longer explicitly set to?null. Why would this make a difference? Isn't the default value for reference type fields (such as?String?here)?null?anyway? Of course, it is. However it turns out that this tiny little change - which apparently would not change the code's behavior in any way - makes this thing fly or not fly.
So what is going on? It becomes clear when looking at the initialization order:
  • main()?calls the?Lower?constructor.
  • An instance of?Lower?is prepared. That means, all fields are created and populated with default values, i. e.?null?for reference types,?false?for?booleans and so on. At this time, any inline assignments to the fields have?not?taken place!
  • The super-constructor is called. This is mandated by the language spec. So, before anything else happens,?Upper's constructor is called.
  • The?Upper?constructor runs and hands a reference to the freshly created instance to the?Initializer.initialize()?method.
  • The?Initializer?attaches new?Strings to both fields. It does so by using a somewhat dirty?instanceof?check - not a particularly good design pattern, but possible, nevertheless. Once that has happened, both the?upperString?lowerString?references are no longer?null.
  • The?Initializer.initialize()?call finishes, as does the?Upper?constructor.
  • Now it becomes interesting: Construction of the?Lower?instance continues. Assuming there is no explicit?=null?assignment in the?lowerString?field declaration, the?Lower?constructor resumes execution and prints out the two Strings that are attached to the fields.
    However, if there?is?an explicit assignment to?null, execution has a slightly different flow: Just after the super constructor is done, any variable initializers are executed (see?section 12.5 of the Java Language Spec),?before?the rest of the constructor is run. In this case the?String?reference that was previously assigned to?lowerString?is now overwritten with?null?again! Only then does the rest of the constructor continue execution, now printing?lowerString: null.
  • Apart from being a nice example for why it is handy to be aware of some of the minutiae of object creation (or knowing where to look in the JLS, printed or online) this shows why it is a bad idea to write the?Initializer?like this. It should not be aware of?Upper's subclasses at all! Instead, if for some reason initialization of certain fields cannot be done in the?Lower?class itself, it will just require its own variant of some sort of initialization helper. In that case, it would really make no difference if you used?String lowerString;?or?String lowerString = null;?- just as it should be.
    From:http://www.danielschneller.com/2010/07/java-object-initialization-order-know.html

    總結

    以上是生活随笔為你收集整理的Java 对象初始化过程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。