java 构造方法
Posted 远方的人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 构造方法相关的知识,希望对你有一定的参考价值。
1. 自定义了构造方法,默认的构造方法还会创建吗,为什么?
自定义了构造方法,则不会再提供隐藏的无参构造方法。
问题: 为什么java 在自定义构造方法后,不在提供隐藏的构造方法呢?
构造方法的作用是初始化成员变量,用户自定义了构造方法自然是像创建一个有特定初始值的对象,如果此时还默认提供隐式构造方法,
那么外部就可以创建一个不符合作者预期的对象。
举个例子:
public class Rect { private float width; private float height; public Rect(float width, float height) { if (width <= 0 || height <= 0) { // 参数不合理时抛出异常 throw new IllegalArgumentException( String.format("Size must > 0. w: %f, h: %f", width, height)); } this.width = width; this.height = height; } }
2. 父子类
问题1: 如果父类定义了一个带参的构造方法, 此时子类也定义了带参数的构造函数,这是会报错
Implicit super constructor P() is undefined. Must explicitly invoke another constructor
意思是父构造器没有定义,必须明确一个其他构造器。
原因是java 中创建子类时需要创建父类,子类会默认调用父类的隐藏构成方法。
但是你自定义了父构造方法,此时子类就找不到默认的构造方法了。所以需要你明确指定调用哪个父构造器。
两种方法解决:
1. 显示写出父类默认构造方法
2. 在子类构造器方法中明确调用父类哪个构造器 如 super(name);
package test; 方案1 : class P{ static {System.out.println("P static");} { System.out.println("P con"); } public P(){ System.out.println("默认p"); } public P(String name){ System.out.println("带参p"); } } class C extends P{ static {System.out.println("C static");} { System.out.println("C con"); } public C(){ } public C(String name){ System.out.println("带参c"); } } public class Test5 { public static void main(String[] args) { C c = new C("张三"); } }
方案2 :
package test;
class P{
static {System.out.println("P static");}
{
System.out.println("P con");
}
public P(String name){
System.out.println("带参p");
}
}
class C extends P{
static {System.out.println("C static");}
{
System.out.println("C con");
}
public C(){
super("");
}
public C(String name){
super(name);
System.out.println("带参c");
}
}
public class Test5 {
public static void main(String[] args) {
C c = new C("张三");
}
}
3. 创建子类对象 调用顺序
package test; class P{ static {System.out.println("P static");} { System.out.println("P con"); } public P(String name){ System.out.println("带参p"); } } class C extends P{ static {System.out.println("C static");} { System.out.println("C con"); } public C(){ super(""); } public C(String name){ super(name); System.out.println("带参c"); } } public class Test5 { public static void main(String[] args) { C c = new C("张三"); } }
结果:
P static
C static
P con
带参p
C con
带参c
所以执行顺序是: 父静态块 - 子静态块 - 父构造块 - 父构造方法 - 子构造块 - 子构造方法
注意: 父构造方法调用哪个问题:
如果没有指定那么就是默认 构造方法
如果指定了(如本例 super(name) ), 则是 调用 父类的 带参构造方法 。。。
以上是关于java 构造方法的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 中创建构造函数的代码片段或快捷方式
无法解析片段中的 ViewModelProvider 构造?
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段