亲宝软件园·资讯

展开

java 构造器(构造方法)使用详细说明

铭言明语 人气:0
# 知识点 - **什么是构造器** 构造器通常也叫构造方法、构造函数,构造器在每个项目中几乎无处不在。当你new一个对象时,就会调用构造器。构造器格式如下: ```java [修饰符,比如public] 类名 (参数列表,可以没有参数){ //这里不能有return } ``` - **默认构造器** 如果没有定义构造器,则会默认一个无参构造器,这就是为什么你定义了一个对象,比如 People,没有定义任何构造器却可以new这个对象,比如 new People() 。如果自定义了构造器,则会覆盖默认构造器。 - **如何禁止对象被外部创建** 一些特殊需求,不希望定义的对象被外部创建(典型的就是单例了),那直接将构造器的修饰符改为 private 即可。这样就不能在外部通过new来创建这个对象了。 - **构造器重载** 与普通方法一样,构造器也支持重载。一个对象中是可以支持同时定义多个构造器,通过不同的参数列表来实现重载。经常看到代码中new一个对象时,有时传入参数,有时又可以不用传。比如:new People()跟new People("张三"),这里就是重载了。 - **构造器的继承** 子类构造器会默认调用父类无参构造器,如果父类没有无参构造器,则必须在子类构造器的第一行通过 super关键字指定调用父类的哪个构造器,**具体看下文例子**。final类是不允许被继承的,编译器会报错。很好理解,由于final修饰符指的是不允许被修改,而继承中,子类是可以修改父类的,这里就产生冲突了,所以final类是不允许被继承的。 - **构造器、静态代码块、构造代码块的执行顺序,详见下文实例** * 无继承的情况下的执行顺序 **静态代码块**:只在程序启动后执行一次,优先级最高 **构造代码块**:任何一个构造器被调用的时候,都会先执行构造代码块,优先级低于静态代码块 **构造器**:优先级低于构造代码块 _总结一下优先级:静态代码块 > 构造代码块 > 构造器_ * 有继承的情况下的执行顺序: **父类静态代码块**:只在程序启动后执行一次,优先级最高 **子类静态代码块**:只在程序启动后执行一次,优先级低于父类静态代码块 **父类构造代码块**:父类任何一个构造器被调用的时候,都会执行一次,优先级低于子类静态代码块 **父类构造器**:优先级低于父类构造代码 **子类构造代码块**:子类任何一个构造器被调用的时候,都会执行一次,优先级低于父类构造器 **子类构造器**:优先级低于子类构造代码块 _总结一下优先级:父类静态代码块 > 子类静态代码块 > 父类构造代码块 > 父类构造器 > 子类构造代码块 > 子类构造器_ # 实例 ## 1.默认构造器 新建一个类,不提供任何构造器,编译器会默认提供一个无参构造器,这就是为什么没定义任何构造器,却可以new 某个对象() ```java public class People { } ``` 以上这个People类,可以直接通过 new People()来实例化。 ## 2. 禁止对象被外部创建 如果不希望People在外部通过new People()来实例化,只需要将构造器定义为private ```java public class People { private People(){ } } ``` ## 3.构造器重载 重载可以简单理解为:同个方法名,不同的参数列表。如果希望People能在外部通过new People() 或 new People("字符串") 来实例化,则通过以下代码即可 ```java public class People { //通过new People()调用 public People(){ } //通过new People("字符串") 调用 public People(String str){ } } ``` ## 4.构造器的继承 定义父类构造器,由于该构造器自定义了一个带参构造器,覆盖了默认的无参构造器,所以不能直接 new SuperClass() 调用了,除非再定义一个无参构造器 ```java /** * 父类构造器 */ public class SuperClass { /** * 自定义带参构造器 */ public SuperClass(String str){ System.out.println("父类的带参构造方法,参数为:" + str); } } ``` 定义子类构造器,继承SuperClass,由于SuperClass没有无参构造器,所以必须在子类构造器中通过 super("字符串")来调用,否则编译器会报错 ```java /** * 子类构造器 */ public class SubClass extends SuperClass { /** * 无参构造器 */ public SubClass(){ //由于SuperClass没有无参构造器,所以必须在子类构造器中通过 super("字符串")来调用,否则编译器会报错。 //如果没定义该句,则编译器会默认调用 super() super(""); } /** * 带参构造器 */ public SubClass(String subStr){ //由于SuperClass没有无参构造器,所以必须在子类构造器中通过 super("字符串")来调用,否则编译器会报错。 //如果没定义该句,则编译器会默认调用 super() super(subStr); } } ``` ## 5. 构造器、静态代码块、构造代码块的执行顺序 ### 5.1 无继承的情况 ```java public class People { static { System.out.println("静态代码块,程序启动后执行,只会执行一次"); } /** * 默认的无参构造器 */ public People(){ System.out.println("默认构造器"); } /** * 构造器重载,自定义一个带参构造器 * @param str */ public People(String str){ System.out.println("带参构造器,参数:" + str); } { System.out.println("构造代码块,每次调用构造方法都会执行一次"); } } ``` 实例化People ```java public static void main(String[] args){ System.out.println("--------------people----------------"); People people = new People(); System.out.println("--------------people1----------------"); People people1 = new People("张三"); } ``` 执行以上代码,输出: ```java --------------people---------------- 静态代码块,程序启动后执行,只会执行一次 构造代码块,每次调用构造方法都会执行一次 默认构造器 --------------people1---------------- 构造代码块,每次调用构造方法都会执行一次 带参构造器,参数:张三 ``` ### 5.2 有继承的情况 定义父类SuperClass ```java /** * 父类构造器 */ public class SuperClass { { System.out.println("父类构造代码块,每次调用构造方法都会执行的"); } /** * 父类无参构造方法 */ public SuperClass(){ System.out.println("父类的默认构造方法"); } /** * 重载,自定义父类带参构造方法 * @param str */ public SuperClass(String str){ System.out.println("父类的带参构造方法,参数为:" + str); } static { System.out.println("父类的静态代码块,程序启动后执行,只会执行一次"); } } ``` 定义子类SubClass,继承SuperClass ```java /** * 子类构造器,继承SuperClass */ public class SubClass extends SuperClass { static { System.out.println("子类的静态代码块,程序启动后执行,只会执行一次,先执行父类的,再执行子类的"); } { System.out.println("子类构造代码块,每次调用构造方法都会执行的"); } /** * 无参构造器 */ public SubClass(){ //这里没有指定调用父类哪个构造器,会默认调用 super(),调用父类的无参构造器public SuperClass() } /** * 重载构造器,多传两个参数 * @param str * @param str1 */ public SubClass(String str,String str1){ //必须写在构造器第一行,调用父类构造器 public SuperClass(String str) super(str); System.out.println("子类带参构造器:" + str1); } } ``` 实例化SubClass ```java public static void main(String[] args){ System.out.println("--------------subClass1----------------"); SubClass subClass1 = new SubClass(); System.out.println("--------------subClass2----------------"); SubClass subClass2 = new SubClass("子类第一个参数","子类第二个参数"); } ``` 执行以上代码,输出: ```java --------------subClass1---------------- 父类的静态代码块,程序启动后执行,只会执行一次 子类的静态代码块,程序启动后执行,只会执行一次,先执行父类的,再执行子类的 父类构造代码块,每次调用构造方法都会执行的 父类的默认构造方法 子类构造代码块,每次调用构造方法都会执行的 --------------subClass2---------------- 父类构造代码块,每次调用构造方法都会执行的 父类的带参构造方法,参数为:子类第一个参数 子类构造代码块,每次调用构造方法都会执行的 子类带参构造器:子类第二个参数 ``` # 源码获取 以上示例都可以通过[我的GitHub](https://github.com/simonxie/javase-demo)获取完整的代码,[点击获取](https://github.com/simonxie/javase-demo/tree/master/src/main/java/com/simon/constructdemo)

加载全部内容

相关教程
猜你喜欢
用户评论