【JavaSE基础】对象的构造及初始化

一、对象的初始化 

1、如何初始化对象

通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。 

public class TestDemo {
    public static void main(String[] args) {
        int a;                    //变量a没有进行初始化
        System.out.println(a);
    }
}
 
//会报出编译错误:Variable 'a' might not have been initialized  

        通过上述代码知道,局部变量一定要初始化,只要进行初始化就不会报出未初始化的错误!那定义一个类内的成员变量是否也需要初始化呢?

(1)我们在实例化一个对象后,可以通过引用变量名访问对象的属性来进行初始化。 以下面代码为例:

class Person{
    public String name;
    public int age;
    public String sex;
    public void show(){
        System.out.println(this.name+"的年龄为"+this.age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
       Person person=new Person();       //实例化对象
       //初始化
           person.name="李华";        
           person.age=13;
           person.sex="boy";
       //打印
           person.show();
    }
}
//运行结果:李华的年龄为13
 

(2)我们也可以在类中定义一个成员方法,通过调用这个成员方法将实参传过去进行初始化。

class Person{
    public String name;
    public int age;
    public String sex;
 
    public void set(String name,int age,String sex){
        this.name=name;
        this.age=age;
        this.sex=sex;
    }

    public void show(){
        System.out.println(this.name+"的年龄为"+this.age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
       Person person=new Person();
       person.set("李华",13,"boy");
       person.show();
    }
}
 
//运行结果:李华的年龄为13

(3)成员变量不进行初始化,代码正常运行,打印出来的是对应基本数据类型的默认值。 

class Person{
    public String name;
    public int age;
    public String sex;
 
    public void show(){
        System.out.println(this.name+"的年龄为"+this.age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
       Person person=new Person();
       person.show();
    }
}
 
对于类中成员变量的初始化可以分为两种,分别是 就地初始化默认初始化

2.就地初始化 

 当我们在类中声明成员变量的同时,直接给成员变量赋值,就称其为“就地初始化”!

class Person{
    public String name="LiHua";
    public int age=13;
    public String sex="boy";
 
    public void show(){
        System.out.println(this.name+"的年龄为"+this.age+"性别为:"+this.sex);
    }
}
public class TestDemo {
    public static void main(String[] args) {
       Person person=new Person();
       person.show();
    }
}
 
//运行结果:LiHua的年龄为13性别为:boy

【注意】:代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中.

3、默认初始化

当我们声明成员变量后,后续并未对其进行初始化,该成员变量就会被编译器设置为默认值。

class Person{
 public int a;
 public short b;
 public long c;
 public float d;
 public double e;
 public boolean f;
 public String g;
 public byte h;
  public void show(){
 System.out.println(this.a+"\n"+this.b+"\n"+this.c+"\n"+this.d+"\n"+this.e+"\n"+this.f+"\n"+this.g+"\n"+this.h);
  }
}
public class Test {
  public static void main(String[] args) {
 Person person=new Person();
 person.show();
  }
}
//结果:
//0
//0
//0
//0.0
//0.0
//false
//null
//0
数据类型默认值
int 0
short0
long 0L
float0.0f
double0.0
boolean

false

char'\u0000'
byte0

二、构造方法
        2.1概念

        构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次  

public class Date {
    public int year;
    public int month;
    public int day; 
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)方法被调用了"); 
    }
 
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day); 
    }
 
    public static void main(String[] args) {
        // 此处创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2022,4,5);
        d.printDate();
    }
}
 //输出:
 //Date(int,int,int)方法被调用了
 //2022-4-5

        在实例化对象时,编译器自动调用new关键词后面的Date()构造方法,但类中的成员变量总是得先进行初始化后才进行构造方法的调用。

       2.2 特性

 1、 名字与类名相同,没有返回值类型,设置为void也不行
 2、在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次             
 3、绝大多数情况下使用public来修饰,特殊场景下会被private修饰
 4、构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)                                         5、实例化对象时,会根据构造方法传过去不同的参数列表,调用相对应的构造方法。 

class Person{
    public String name;
    public int age;
    public String sex;
 
    public Person(){      //无参构造方法
        System.out.println("无参构造方法");
    }
    public Person(String name,int age){     //带两个参数的构造方法
        this.name=name;
        this.age=age;
        System.out.println("带两个参数的构造方法");
    }
}
public class TestDemo {
    public static void main(String[] args) {
       Person person=new Person();
       Person person1=new Person("LiHua",15);
    }
}
 
//运行结果;无参构造方法
//         带两个参数的构造方法

        1.3 注意

1、构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间 。                      2、一旦用户自定义了带参的构造方法,编译器就不再为我们自动提供一个默认的不带参数的构造方法,这时需要我们必须动手写无参构造方法。

public class Date {
    public int year;
    public int month;
    public int day;
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
    }
    public static void main(String[] args) { 
        Date d = new Date();
        d.printDate();
    }
}
 

//此处虽然有自己定义一个构造方法,但这个构造方法是带三个参数的,
//在实例化对象时并没有传三个参数过去,是无参的。
//而我们自己定义后,编译器是不会再自动提供默认的无参构造方法,所以该代码才报错。
//正确的做法是再添加一个无参的构造方法,或在实例化对象的时候传三个参数给构造方法。 

        1.4   this()

在构造方法中,可以通过this调用其他构造方法来简化代码

class Person{
    public String name;
    public int age;
    public String sex;
 
    public Person(){
        this("LiHua",17);
        System.out.println("无参构造方法");
    }
    public Person(String name,int age){
        this.name=name;
        this.age=age;
        System.out.println("带两个参数的构造方法");
        System.out.println(this.name+"年龄为:"+this.age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
       Person person=new Person(); 
    }
}
//结果:
//带两个参数的构造方法
//LiHua年龄为:17
//无参构造方法
//总是先执行完this()调用的构造方法,再回到原本的构造方法进行执行。

【注意】:

1、在构造方法中使用this()调用其他的构造方法,this()调用语句一定要放在第一行,因为this()一定得首先运行。

2、因为this()只能放在第一行优先执行,所以一个构造方法里面只能调用一个this(),否则它们都想优先执行,没法都在第一行。

3、不能使用this()调用构造方法形成闭环。

public Date(){
    this(1900,1,1);
}
public Date(int year, int month, int day) {
    this();
}
//无参构造器调用三个参数的构造器,而三个参数构造器又调用无参的构造器,形成构造器闭环
//编译报错:Error:(19, 12) java: 递归构造器调用

三、new关键字

对于实例化一个对象的语句,该语句不单单只是一个简单的语句,,在JVM层面需要做好多事情,下面简单介绍下:

 1. 检测对象对应的类是否加载了,如果没有加载则加载;

由.java文件编译成.class文件时,一个字节码文件对应一个类,当用到类的时候要加载它。

2. 为对象分配内存空间; 

3. 处理并发安全问题 比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突。

 (当有多线程时,为同一个对象分配一块内存,就会出现并发安全问题。为了避免发生冲突,你不能每一个线程在分配内存时,都分配到同一个地址,多个对象没法放进去同一个地方。)  

四、总结 

在本章节中介绍了对象的初始化和构造方法。

要点:

1、构造方法的本质:当我们实例化一个对象的时侯,一定会进行两步操作:(1)为对象分配内存  (2)调用合适的构造方法。

2、构造方法是一个没有返回值,类名相同,参数列表不同的多个方法。

3、当写一个类时,编译器会帮我们默认生成一个不带参数的构造方法;但只要我们用户自己定义了一个构造方法,编译器就不会再默认生成一个。(一个类中至少会有一个构造方法,即使用户没有定义)。

4、可以通过this()调用构造方法,但只能在构造方法中使用(在同一个构造方法内也就只能使用一次 )。而且必须放在构造方法内第一行。

5、this()不能形成“闭环”。   

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值