如果Java中存在用户定义的构造函数,则初始化变量

如果Java中存在用户定义的构造函数,则初始化变量,java,constructor,Java,Constructor,在下面的代码中,我有一个用户定义的构造函数(没有参数构造函数)和一个参数化的构造函数 我的理解是,如果我至少有一个构造函数,编译器不会添加默认/隐式构造函数 我的问题: 在main方法中,我通过调用参数化构造函数创建Employee对象。在参数化构造函数中,我只设置empId属性 当我尝试打印name的值时,它会将其打印为null(即默认值) 是什么将名称初始化为NULL(即默认值)? 它不能是编译器生成的隐式/默认构造函数,因为类中至少有一个构造函数 public class Employee

在下面的代码中,我有一个用户定义的构造函数(没有参数构造函数)和一个参数化的构造函数

我的理解是,如果我至少有一个构造函数,编译器不会添加默认/隐式构造函数

我的问题:

在main方法中,我通过调用参数化构造函数创建
Employee
对象。在参数化构造函数中,我只设置
empId
属性

当我尝试打印name的值时,它会将其打印为null(即默认值)

是什么将名称初始化为NULL(即默认值)? 它不能是编译器生成的隐式/默认构造函数,因为类中至少有一个构造函数

public class Employee {

    String name;
    int empId;

    public Employee() {
        System.out.println("Calling User Defined Constructor");
    }

    @Override
    public String toString() {

        return "name=" + name + " empId=" + empId;

    }

    public Employee(String name, int empId) {
        this.empId = empId;
    }

    public static void main(String[] args) {

      Employee e = new Employee("test",123);

        System.out.println(e);
    }

}

引用类型的类变量的默认值为null(与没有默认值的局部变量相反)。类似地,基元类型的类变量也有自己的默认值

您的代码相当于:

public class Employee {

    String name = null;
    int empId = 0;
    ...
}
JLS为营救工作提供帮助:

对于所有引用类型(),默认值为null

由于
String
是一种引用类型,因此默认值为
null

ReferenceType:
    ClassOrInterfaceType
    TypeVariable
    ArrayType
考虑在构造函数中指定它:

public Employee(String name, int empId) {
    this.empId = empId;
    this.name = name;
}

Employee类中的
字符串名称
在声明时隐式为null,即

String name=null


任何引用类型变量(如本例中的字符串)的默认值均为null


构造函数按如下方式执行:

  • 所有字段均为“零”<代码>空,0,0.0,'\u0000'
  • 调用超级构造函数,或者显式调用隐式
    super()
  • 所有字段初始化都会发生;这只是那些
    =…
    的字段
  • 其余的构造函数代码将被执行
  • 您可能会发现以下谜题(打印的是什么?)很有启发性

    class A {
        A() {
            terrible();
        }
        protected void terrible() {
            System.out.println("A.terrible - " + this);
        }
    
    }
    
    class C extends A {
        C() {
            System.out.println("C.terrible - " + this);
        }
    
        String a;
        String b = null;
        String c = "c";
    
        @Override
        protected void terrible() {
            System.out.println("C.terrible - " + this);
            a = "aa";
            b = "bb";
            c = "cc";
            System.out.println("C.terrible (2) - " + this);
        }
    
        @Override
        public String toString() {
            return String.format("a=%s, b=%s, c=%s", a, b, c);
        }
    }
    
    根据您的实例,构造函数将在运行时加载

    Construtor在初始化对象本身时设置值


    因此,在您的情况下,只创建了一个实例。。它传递了两个值。但是只指定一个值。因此name默认设置为null….

    字段的默认值不由任何Java代码分配;它是VM,它在开始执行构造函数之前对对象的内存进行本机初始化。如果不这样做,人们可能会从已经gc'ed的对象中读取虚假数据,这将是一种安全风险,尤其是对于对象引用。“我只设置empId属性”-在没有setter和getter的情况下,如何设置empId值?
    this.empId=empId:)我的假设是,在任何构造函数调用之后,变量都会初始化为默认值。那么你的意思是,即使在调用构造函数之前,VM也会将实例变量默认为某个值??我的假设是,正是构造函数将变量初始化为默认值。根据您的解释,VM似乎在调用构造函数之前将它们初始化为默认值。是这样吗?@ankurlu这是正确的。它们在构造函数执行之前被初始化。当然,构造函数可以更改这些默认值。非常感谢。这回答了我的问题
    
    class A {
        A() {
            terrible();
        }
        protected void terrible() {
            System.out.println("A.terrible - " + this);
        }
    
    }
    
    class C extends A {
        C() {
            System.out.println("C.terrible - " + this);
        }
    
        String a;
        String b = null;
        String c = "c";
    
        @Override
        protected void terrible() {
            System.out.println("C.terrible - " + this);
            a = "aa";
            b = "bb";
            c = "cc";
            System.out.println("C.terrible (2) - " + this);
        }
    
        @Override
        public String toString() {
            return String.format("a=%s, b=%s, c=%s", a, b, c);
        }
    }
    
    public Employee(String name, int empId) {
    
        this.empId = empId;
    }
    
    
    public Employee() {
        System.out.println("Calling User Defined Constructor");
    }