JAVA中的构造器和this关键字

JAVA中的构造器(构造方法)

 构造器:构造器是一种方法,它的作用就是完成对对象的初始化

我们以前写代码是现将对象创建好,然后在该对象中的属性赋值,比如像下面这样:

public class Test{
    public static void main(String[] args){
        Person people = new People();
        people.name = "冬泳怪哥";
        people.age = 40;
        people.hobit = "游泳";
    }
}

class People{
    String name1;
    int age;
    String hobits;    
}

这样赋值比较麻烦,为了解决这个问题,java开发者就写了一个构造器,它的作用就是帮助完成对象的初始化,我们要做的就是在创建对象的时候就完成对对象的初始化。列如像下面这样: 

public class Test{
    public static void main(String[] args){
        Person people = new People("冬泳怪哥",40,"游泳");
    }
}

class People{
    String name1;
    int age;
    String hobits;
    
    //构造器是创建
    public void People(String name,int age,String hobit){
        this.name = name;
        this.age = age;
        this.hobit = hobit;
    }    
}

构造器的基本语法 

修饰符 方法名 (形参列表){
    方法体;
}
  • 构造器的修饰符可以默认(就是什么都不写),也可以是public、protected、private
  • 构造器没有返回值(不用写void)
  • 方法名和类名的名字必须一样
  • 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化
  • 一个类可以定义多个构造器,即构造器重载
  • 如果我们没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器)
  • 一旦定义了自己的构造器,默认的构造器就被覆盖了,就不能在使用默认的无参构造器,除非显示的定义一下。

演示系统的默认无参构造器

 

我在Teacher这个类里面没有写构造器,看看利用javap反编译的结果

从上面可以看到,系统默认给我们创建了一个无参构造器 ,只不过这里只声明了,所以Teacher()后面没有根{}。

显示定义无参构造器
People(){

}
构造器里面什么都不写

this关键字 

在上面讲解构造器时,我们在写构造器的时候,构造器里面有一个关键字this。那this是什么,它有什么作用。

举个例子,现在有3个人,张三、李四、王五,它们分别编号1、2、3。它们被叫去办公室,第一个被叫去的是1,那么this就指代张三;第二个被叫去的是3,那么this就指代王五。

this关键字:this代表当前对象

演示this在内存中的情况

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("哈巴狗", 3);
        System.out.println("当前对象的哈希码值:"+dog.hashCode());
        System.out.println("===================");
        Dog dog1 = new Dog("财犬", 2);
        System.out.println("当前对象的哈希码值:"+dog1.hashCode());
    }
}
class Dog{
    String name;
    int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("当前对象的哈希码值:"+this.hashCode());
    }
}

this关键字的细节 

this关键字可以用来访问本类的属性、方法、构造器

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}
class Dog{
    String name = "李华";
    int age = 20;

    public Dog(){
        this.eat();
    }
    public void eat(){
        System.out.println("name = "+this.name+"age = "+this.age);
        System.out.println("干了,兄弟们");
    }
}

this用于区分全局变量和局部变量

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}
class Dog{
    String name = "李华";
    int age = 20;

    public Dog(){
        this.eat();
    }
    public void eat(){
        String name = "蔡徐坤";
        System.out.println("name = "+name+"age = "+this.age);
        System.out.println("干了,兄弟们");
    }
}

访问成员方法的语法:this.方法名(参数列表)

访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在第一条语句)

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}
class Dog{
    String name;
    int age;

    public Dog(){
        this("哈密瓜",10);
        System.out.println("你就笑吧");
    }
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("指定没你好果子吃");
    }
}

this不能在类定义的外部使用,只能在类定义的方法中使用

拓展

对象创建的流程分析 

以下面这个案例来分析

class Test{
    public static void main(string[] args){
        Person people = new Person("ikun",20);
    }
}

class Person{
    int age = 999;
    String name;
    Person(String a,int b){
        this.name = a;
        this.age = b;
    }
}

 流程图:

分析:

第一步:创建对象,在方法区里面加载Person类信息(包括属性信息、方法信息)

第二步:在堆区中为成员变量开辟空间,并且默认初始化(age默认初始化为0,name默认初始化为null)

第三步:显示初始化,将age初始化为999,name因为没有被赋值,所以还是null

第四步:调用构造方法,完成构造方法的初始化。age被初始化为20,name被初始化为ikun。

因为“ikun”是字符串常量,所以在方法区里面的常量池中,并返回一个地址给到堆区的name空间

第五步:将堆区中的地址返回给栈区的引用变量people

总结:

  1. 加载Person类信息
  2. 在堆区中分配空间
  3. 完成对象初始化
  4. 把对象在堆中的地址返回给person

JAVA中的作用域

分类:

全局变量:类中的属性就是全局变量,作用域为整个类体

局部变量:除了全局变量以外的其他变量,作用域为定义它的代码块中

演示全局变量和局部变量

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

class People{
    String name1 = "李华";
    int age = 20;
    String hobits = "唱,跳,rap,篮球";

    public void say(){
        int n1 = 100;
        String name2 = "鸡";
        System.out.println("全名制作人们,大家好,我是鸡鸡");
    }
    
    public void modify(){
        name1 = "蔡徐坤";//这里是可以的,因为name1是全局变量,全局变量的作用域在整个类中
        age = 3;//这里是可以的,因为age是全局变量
        System.out.println("姓名:+"name+"年龄:+"age);
    }

    public void modefys(){
        name2 = "ikun";//这儿不可以会报错,因为name2是局部变量,局部变量的作用域只在它定义的代码块中
    }
    
}

全局变量和局部变量的注意事项

1.全局变量和局部变量可以重名,访问时遵循就近原则。

2.在同一个作用域中(比如同一个代码块、方法中),两个局部变量不能重名。

3.全局变量生命周期长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量生命周期短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。

4.全局变量可以在本类中使用,也可以在其他类中使用;局部变量只能在本类中对应的方法中使用

5.修饰符不同。全局变量可加可不加修饰符,局部变量不能加修饰符。

猜你喜欢

转载自blog.csdn.net/yahid/article/details/125657041