先说明一点,这篇帖子的内容都是我自己思考的结果,如有误,请务必及时告诉我,非常感谢。
起由:
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 }
我认为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 }
另外,得找个时间研究下Java的内存了。