• Java 构造方法的执行过程(猜测)


    先说明一点,这篇帖子的内容都是我自己思考的结果,如有误,请务必及时告诉我,非常感谢。

    起由:

    public class NewThread implements Runnable{
        Thread t;
        NewThread(){
            t = new Thread(this, "Demo Thread");
            System.out.println("Child thread: " + t);
            t.start(); // Start the thread
        }
    
        @Override
        public void run(){
            System.out.println("the thread is running");
        }
    }

    个中详情不必细说,总之我的第一反应就是:卧槽,构造方法中也可以使用this!!!为什么??

    然后认真想了下,又想到C++中类的构造,还真可以。

    C++中的构造过程是这样的:

      先按照成员的大小分配空间,再默认初始化(如果有显式初始化列表,那就通过初始化列表的数据进行初始化),最后执行构造体中的内容。

      如果构造体中有赋值语句,那么整个过程就等于初始化之后再进行赋值!!

    举个栗子:

     1 #include <iostream>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 
     5 using namespace std;
     6 
     7 class A
     8 {
     9 public:
    10     int age;
    11     char name[100];
    12 public:
    13     A(){};
    14     ~A(){};
    15 };
    16 class B
    17 {
    18 public:
    19     int age;
    20     char name[100];
    21 public:
    22     B():age(10),name{'a','b','c'}{}; //c++11,非类类型的初始化列表必须没有()
    23     ~B(){};
    24 };
    25 class C
    26 {
    27 public:
    28     int age;
    29     char name[100];
    30 public:
    31     C():age(10),name{'a','b','c'}{ //c++11,非类类型的初始化列表必须没有()
    32         age = 18;
    33         // name = "wahaha";
    34         strcpy(name, "wahaha"); //还是使用C++的string方便啊
    35     }; 
    36     ~C(){};
    37 };
    38 
    39 int main(int argc, char const *argv[])
    40 {
    41     A a;
    42     B b;
    43     C c;
    44     cout<< a.age <<"--" <<a.name <<endl; //1875728040--
    45     cout<< b.age <<"--" <<b.name <<endl; //10--abc
    46     cout<< c.age <<"--" <<c.name <<endl; //18--wahaha
    47 
    48     return 0;
    49 }
    View Code

    我认为Java应该也是类似的:

      先按照成员的大小分配空间,对分配的空间进行默认操作最后执行构造体中的内容。

      这里有两个地方可能引起疑惑:

        ① 对分配的空间进行默认操作,这个默认操作是什么?我认为Java是将所有空间内容全部置零

          类似C的 memset() 操作。

        ② 对象中的引用类型怎么分配空间? 我在前面的文章有提到,Java的引用变量其实更像C++的指针。这样就能完美解释对象中的 默认类型和引用类型的初始化值:都是0,对指针来说就是NULL(C++概念)--Java里就是null。如果能观察Java对象的内存占用,就能直观的观察到这些,特别是引用类型变量的内存占用。(别忘了类的对象本身是在堆中)

        话又说回来,各种Java书籍中明确告知了独立的引用类型的变量是存储在栈空间,指向堆中的内容!所以完全可以将引用类型的变量看作指针!!!

    举个栗子:

     1 public class A {
     2     public A(){
     3         System.out.println("A 默认构造");
     4     }
     5 }
     6 //-------------
     7 public class B {
     8     private String name;
     9     private int age;
    10     private A a;
    11 
    12     public B(){
    13         System.out.println(this);
    14         System.out.println(name);
    15         System.out.println(age);
    16         System.out.println(a);
    17         run();
    18         System.out.println("B 无参构造");
    19     }
    20 
    21     public void run(){
    22         System.out.println("hehe from B.run()");
    23     }
    24 }
    25 //-------------
    26 import org.junit.Test;
    27 public class Test1 {
    28 
    29     @Test
    30     public void run1(){
    31         B b = new B();
    32     }
    33 }
    View Code

    另外,得找个时间研究下Java的内存了。

      

  • 相关阅读:
    centos中文乱码修改字符编码使用centos支持中文
    java知识总结-26
    java知识总结-25
    java知识总结-24
    java知识总结-23
    java知识总结-22
    java知识总结-21
    java知识总结-20
    java知识总结-19
    java知识总结-18
  • 原文地址:https://www.cnblogs.com/larryzeal/p/5670949.html
Copyright © 2020-2023  润新知