一键搞定内网穿透 联行号查询|开户行查询 在线工具箱 藏经阁
当前位置:首页 / 杂记 / 正文
java构造函数
参考
https://www.cnblogs.com/itmlt1029/p/4765147.html

1. 函数名与类名相同。

2. 可使用public/private/protected修饰符,修饰符也可省略(最好不要省略);如果构造函数修饰符为private,则不能通过这个构造函数创建对象;如果构造函数修饰符为protected,则只有继承它的子类可以创建对象。
public class A {
 private A(){}
}
new A(); //报错
public class A {
 protected A(){}
}
new A(); //报错
public class A {
 protected A(){}
}
public class B extends A {
}
new B(); //正确
3. 不要指定返回值类型,使用void也不行,如果加上void后,jvm就不会把它当成构造函数了,当成了普通函数;严格说void也是指定了返回值类型的,它的类型是"无返回值"类型,两者是有区别的。

4. 普通函数必须指定返回类型,如是没有返回值就使用void。

5. 如果不声明构造函数,JVM会默认生成一个无参构造函数。如果声明了带参数的构造函数,JVM默认不会生成无参构造函数,想要使用无参构造函数就必须自己去显式声明一个无参构造函数。

6. 子类继承父类,子类对象初始化时父类的构造函数也会执行;子类的构造函数中默认的第一行有一条隐式语句super(),该语句会访问父类中的空参数构造函数,除非父类中没有空参数的构造函数,那么子类构造函数的第一行必须显式调用父类的构造函数,即super(int x,…) 。

7. 子类的构造函数中,super()语句代表调用了父类的构造函数;this()语句代表调用了子类自身的构造函数。需要注意的是,如果这两条语句显式写出来必须放在构造方法的第一行,而且这两条语句不能共存,一个构造函数中的第一行要么是this()要么是super()。
 super()和this()只能在构造函数中使用。
 为什么在第一行?因为需要首先进行初始化。
 为什么不能共存?因为this()代表的本类的其他构造函数,也会去调用super(),出现了this()就没有必要再出现super()了,重复调用没有意义。
public class B extends A {
 public B(){
  super(); //必须在第一行,没有它也一样,也会隐式调用super(); 
 }
 public B(int a){
  this(); //必须在第一行,调用该类的无参构造函数B()。
 }
 public B(int a, int b){
  this(2); //必须在第一行,调用该类的带参构造函数B(int a)。
 }
}
8. 构造函数只参在创建对象时调用,或在构造函数之间相互调用。创建的对象不能直接调用构造函数。

9. 构造代码块与构造函数有什么相似和不同?
 构造代码块用一对“{}”表示,代码块位置没有具体的要求,但必须与类的成员同等级别,在括号的区域内,可以对所有该类的对象进行初始化,也就是说该类对象创建时都会执行到该代码块,并且其优先于构造函数执行。
public class A {
 {
  System.out.println("执行构造代码块"); //构造代码块{}前面不要任何修饰符
 }

 public A() {
  System.out.println("执行无参构造函数");
 }

 public A(int i) {
  System.out.println("执行有参构造函数");
 }

 public static void main(String[] args) {
  new A();
  new A(1);
  //输出
  执行构造代码块
  执行无参构造函数
  执行构造代码块
  执行有参构造函数
 }
}
10. 成员变量的赋值初始化优先于构造函数。看以下例子
public class Test {
 Person person = new Person();
 public Test() {
  System.out.println("test constructor");
 }

 public static void main(String[] args) {
  new Test();
 }
}

class Person{
 public Person() {
  System.out.println("person constructor");
 }
}
//输出
person constructor
test constructor
如果成员变量在声明时被显式初始化,那么就把初始化值赋给成员变量,然后再执行构造方法。
如果成员变量没有显示赋值,则自动初始化为其变量类型的默认值,然后再执行构造方法。

11. 类初始化顺序

初始化的顺序是:先静态对象(如果它们尚未因前面的对象创建过程而被初始化),而后是非静态对象。在类的内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
总结对象创建的过程:
(1)首次创建对象时,类中的静态方法/静态字段首次被访问时,java解释器必须先查找类路径,以定位.class文件;(2)然后载入.class(这将创建一个class对象),有关静态初始化的所有动作都会执行(静态变量的初始化和静态代码块执行顺序按代码书写顺序依次执行,静态变量和静态代码块是平级的)。因此,静态初始化只在Class对象首次加载的时候进行一次。(3)当用new XX()创建对象时,首先在堆上为对象分配足够的存储空间。(4)这块存储空间会被清0,这就自动地将对象中的所有基本类型数据都设置成了缺省值(对数字来说就是0,对布尔型和字符型也相同),而引用则被设置成了null。(5)执行所有出现于字段定义处的初始化动作(非静态对象的初始化)。(6)执行构造器。