初识java——javaSE(4)类与对象

news2025/1/18 6:55:28

文章目录

  • 前言
  • 一 类与对象
    • 1.1 面向过程与面向对象思想的区别:
    • 1.2 类的定义
    • 1.3 类的实例化——对象
      • 通过创建对象,调用对象中的成员变量与方法
    • 1.4 this关键字
      • this的作用一:
      • this 的作用二
        • 构造方法:
          • 对象创建的两步
          • 方法的重载
      • this的作用三 :
    • 1.5 封装
        • getter与setter方法
    • 1.6 public 与private是什么?
    • 1.7 包
        • jdk中提供的供开发的包,
        • 用户自己创建包
        • 当前类如何引用其他包中的类?(导包?)
        • 导入外部包中类的静态方法与静态字段
          • 对于java提供的包:
    • 1.8 访问修饰限定符
    • 1.9 static静态修饰符
        • static修饰成员变量:
        • static修饰成员方法:
        • 静态方法与非静态方法的相互调用?
        • 静态方法与非静态成员变量?
        • 静态方法与this 关键字?
        • 静态成员变量的初始化:
    • 2.0 代码块
        • 普通代码块:
        • 构造代码块(实例代码块)
        • 静态代码块
        • 两种代码块(普通代码块忽略)与构造方法的执行先后顺序
    • 2.1 对象的打印


前言


一 类与对象

1.1 面向过程与面向对象思想的区别:

面向过程的思想关注的是过程,即功能的具体实现,我们之前用c语言编写的代码的思想即是面向过程的思想。
面向对象的思想关注的是对象,即将各个事物看作一个个对象,进行对象之间的调用协作。

举例:
早些时候农村洗衣服的方式:此时我们注重参与洗衣服的过程,——这即是面向过程的思想
在这里插入图片描述
现在农村洗衣服的方式:
在这里插入图片描述
此时,我们只是注重于三个对象,衣服,洗衣粉,洗衣机。至于洗衣机具体是怎样操作的,是我们不注重的,这就是面向对象的思想。

1.2 类的定义

什么是类?

         类相当于一个模型,而对象则是类的具体实现。

类的定义语法:

        类的形式:
          class 类名 {
            成员变量;
            成员方法;
       
              }

:对于public修饰的类,一个文件中只能有一个,且文件名与此类名必须相同。

举例:

   class Dog {
        String name; //成员属性(成员变量)名字
        int age;     //成员属性(成员变量)年龄
           //成员方法:
        public static void shout() {
            System.out.println("汪汪..........");
        }
        
      }

本地初始化

    我们是可以直接在给类的成员变量赋予初始值的,但创建对象时,
    成员变量中的值即最后对成员变量修改的值。
public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        System.out.println(dog1.age);
    }
}
class Dog {
    String name; //成员属性(成员变量)名字
    int age = 10;     //成员属性(成员变量)年龄
    //成员方法:
    public static void shout() {
        System.out.println("汪汪..........");
    }
}

在这里插入图片描述

1.3 类的实例化——对象

类相当于一个模型,而对象才是类具体的实现,
类实例化的格式:

类名  对象名 = new 类名();   

new关键字用于创建新的对象,在堆区申请一块的空间,其中存放对象中成员变量的值。

:当对象创建时,栈会自动分配一段内存,用于存储该对象的局部变量

 这个类实例化的形式十分类似于引用类型变量的创建与初始化,
 实际上我们可以将类看做自定义类型,对象就自定义类型的变量。

举例:

   public static void main(String[] args) {
        Dog dog = new Dog();
        Dog dog2 = new Dog();
        dog.set("小黑", 1);
        dog2.set("小黄", 10);
    }
}

如图:
在这里插入图片描述
当对象未初始化时,默认值为

public class test{
  public static void main(String[] args) {
        Dog dog1 = new Dog();
        System.out.println(dog1.age);
        System.out.println(dog1.name);
    }

}

class Dog {
    String name;
    int age;

    public static void shout() {
        System.out.println("汪汪..........");
    }

    public static void set(String name, int age) {
        age = age;
        name = name;
    }
}

在这里插入图片描述

对象未初始化时,遵循的规则是:引用类型数据值为null,基本数据类型为对应的0值(char类型为□,float类型为0.0).

在这里插入图片描述

通过创建对象,调用对象中的成员变量与方法

在目前的学习认知中,均是通过引用对象+点号,来访问对象的成员变量与成员方法!

  public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.shout();
        dog1.setData("小黑",12);
        System.out.println(dog1.age);
        System.out.println(dog1.name);

    }

}

class Dog {
    String name;
    int age;
    
    public static void shout() {
        System.out.println("汪汪..........");
    }
//设置当前对象属性的值
    public static void setData(String name, int age) {
        age = age;
        name = name;

    }
}

在这里插入图片描述

结果表明,第一方法成功实现,第二个方法的实现并没有达到我们预期的效果,dog1的成员属性依然是默认值,
原因在于我们并没有指定将形参中的值传到成员变量中去,
仅仅是name = name;不能代表右边变量中的值传入到成员变量中去,这涉及到一个关键字this。

1.4 this关键字

:this关键字不能在静态方法中使用! (原理在后面的博客中会阐述到)

this的作用一:

                               通过this访问当前对象的成员变量

在上面的例子中,第二个方法的实现并没有达到我们预期的效果,如果在属性名前加上this. 即可赋值成功!

  public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.shout();
        dog1.setData("小黑",12);
        System.out.println(dog1.age);
        System.out.println(dog1.name);

    }

}

class Dog {
    String name;
    int age;

    public static void shout() {
        System.out.println("汪汪..........");
    }

    public  void setData(String name, int age) {
       this. age = age;
       this. name = name;

    }
}

在这里插入图片描述

原理
在未添加this之前,此时形参名与成员变量名相同,此时默认将变量名当做形参名,
也就是成了形参给形参赋值。

那么为什么添加this关键字之后,就成功赋值了呢?假如有多个对象调用方法,
那么它是如何判断当前对象的?

:哪个对象调用了方法,此时this就代表哪个对象,this的本质就是一个形参对象

在这里插入图片描述
因为this形参隐藏了,所以我们在参数列表中看不到它。我们也可以把它写出来

  public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.shout();
        dog1.setData("小黑",12);
        System.out.println(dog1.age);
        System.out.println(dog1.name);

    }

}

class Dog {
    String name;
    int age;

    public static void shout() {
        System.out.println("汪汪..........");
    }

    public  void setData(Dog this,String name, int age) {
       this. age = age;
       this. name = name;

    }
}

在这里插入图片描述

 如图,this中存放的是调用方法的对象的引用。

this 的作用二

通过this访问当前对象的非静态的成员方法
 public test{
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.func1();
    }
}
//  this关键字
class Dog {
    String name;
    int age;

    public  void shout() {
        System.out.println("汪汪..........");
    }
   public void func1(){
   //this调用当前对象的非静态方法
        this.shout();
   }

}

在这里插入图片描述

this的此作用与上一个作用的原理相同!
构造方法:

构造方法的格式:
构造方法与普通方法格式的区别:

普通方法: 修饰符   返回值类型 方法名(形参列表){
                         方法体
}
构造方法 :  修饰符   类名(形参列表){
               方法体
}

构造方法相对于普通方法而言,没有返回值类型,且构造方法的方法名必须与所在类名保持一致!

对象创建的两步

第一步是:用new关键字为对象分配一块内存

Cat cat = new Cat;

第二步是调用合适的构造方法
下面的是调用了无参的构造方法!

Cat cat = new Cat();

构造方法的作用:初始化对象中的成员!

构造方法执行规则: 构造方法在实例化对象后便由系统执行,而不需要再调用。

public class test{

public static void main(String[] args) {
   Cat cat = new Cat();
 }
}
class Cat{
    String name;
    int age ;
    //构造方法:
    public Cat(){
        System.out.println("喵喵........\n");
    }

在这里插入图片描述

方法的重载

一个类中可以有多个构造方法,在创建对象时,我们选择调用合适的构造方法。一个对象只能选择一个构造方法。

 //构造方法
 public static void main(String[] args) {
   Cat cat = new Cat();
  Cat cat1 =new Cat("小红",3);
     System.out.println(cat.age +  cat.name);
     System.out.println(cat1.age+ cat1.name);


 }


}
class Cat{
    String name;
    int age ;
    public Cat(){
        System.out.println("喵喵........\n");
    }
    public Cat(String name,int age){
        this.name = name;
        this.age = age;
    }

}

在这里插入图片描述

结果表明:创建两个对象时,调用的构造方法不同,产生的对象也就不同。

注: 为什么类中没有构造方法,但是依然可以创建对象成功?
这是因为当我们在类中没有创建构造方法时,系统会默认帮我们加上一个无参的构造方法,方法体为空。
但是当已经我们已经创建了构造方法,系统便不再为我们提供无参的构造方法了。

 public static void main(String[] args) {
   Cat cat = new Cat();
  Cat cat1 =new Cat("小红",3);
     System.out.println(cat.age +  cat.name);
     System.out.println(cat1.age+ cat1.name);
 }
}
class Cat{
    String name;
    int age ;
    /*public Cat(){
        System.out.println("喵喵........\n");
    }*/
    public Cat(String name,int age){
        this.name = name;
        this.age = age;
    }

}

在这里插入图片描述

this的作用三 :

this 的第三个作用是 构造函数通过this访问当前对象的其他构造方法!
调用的形式是

           this(参数列表); 因为this本质上是形参对象,对象在调用构造方法时的格式即是
           
           对象名(参数列表);

在这里插入图片描述

     在调用其他构造方法时,本构造方法需将this(参数列表);放在第一行!
public test{
public static void main(String[] args) {
  Cat cat1 =new Cat("小红",3);
 }
}
class Cat{
    String name;
    int age ;
    public Cat(){
        System.out.println("喵喵........\n");
    }
    public Cat(String name,int age){
        this();
        this.name = name;
        this.age = age;

    }
}

在这里插入图片描述
:构造方法不可以相互调用,否则直接变成死循环!

1.5 封装

面向对象思想具有三个特性:封装,继承,多态;这三个特性不仅仅是java语言的特性,是面向对象语言的特性。

java中封装性体现在:将整个类封装起来,而只是留着几个可访问的接口供用户使用。

class Dog{
    public String name;
    public int age;
    public void shout(){
        System.out.println("汪汪......");
    }
    
}
public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.name = "小黑";
        dog1.age = 10;
    }
}

代码分析: 在这段代码中,定义了一个Dog类与测试类,并在测试类中新创Dog对象,直接访问dog1对象中的方法。
在测试类中,可以通过dog1对象直接访问对象中的成员,这使得对象中的数据安全性大大降低,十分容易被修改。
如果将Dog类中成员变量前的修饰符public 改为 private :

在这里插入图片描述
此时便不能够通过对象直接访问修改对象中的成员变量。

getter与setter方法

getter方法用于获取对象当前的成员变量值
setter方法用于设置对象当前的成员变量值

class Dog{
    private String name;
    private int age;
    public void shout(){
        System.out.println("汪汪......");
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
     /*   dog1.name = "小黑";
        dog1.age = 10;*/
        dog1.setAge(10);
        dog1.setName("张三");
        System.out.println(dog1.getAge());
        System.out.println(dog1.getName());
    }
}

在这里插入图片描述
代码解析:
我们通过setter方法与getter方法获得了修改对象属性(成员变量)与获取对象属性的两个专门接口,这提高了对象的数据的安全性,体现了面向对象思想的封装性。

1.6 public 与private是什么?

public ,private,protected 这些称作访问修饰限定符(即管理修饰的属性与方法的访问权限)

几个访问修饰限定符的权限列表:在这里插入图片描述
要彻底理解这个图,需要搞明白,包与子类的概念。

1.7 包

包本质上就是文件夹,一个包中存放着一组类。在一个包中不允许有两个相同名字的类,但是在不同的包中允许有两个名字相同的类。

jdk中提供的供开发的包,

其中在基础包中:
在这里插入图片描述
在这里插入图片描述
点击java文件夹:

在这里插入图片描述
这几个包中包含着java为开发人员提供的类。

比如lang中:
在这里插入图片描述

用户自己创建包

在这里插入图片描述
在这里插入图片描述

 一般规范自建包的名称的格式为:com. 公司名称.www

在这里插入图片描述

 在上图中,package com.bite.www ;语句作用是声明当前类所在的包
当前类如何引用其他包中的类?(导包?)

举例:

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int []arr=new int[]{1,2,3,4,5};
        System.out.println(Arrays.toString(arr));
    }
}

代码分析:
在上面的代码中调用了jdk提供的Arrays类的方法(至于为什么没有创建对象便可引用,下面会阐述到)

    import java.util.Arrays;

其中import是引入包的关键字,其后面跟路径!因为 Arrays类在java包下的util包中,所以示为java .util.Arrays,中间用 . 号连接!

第二种引用方式:
则是将所调类的方法的全路径写在代码中,但是这种方式相较第一种很麻烦,不推荐。

public class Test {
    public static void main(String[] args) {
        int []arr=new int[]{1,2,3,4,5};
        System.out.println(java.util.Arrays.toString(arr));
    }
}

在这里插入图片描述

第三种调用方式
引用语句 只是指定到类所在的包,不指定引用的具体的类,在原来类的位置用 * 替代。*称为通配符!

import java.util.*;

public class Test {
    public static void main(String[] args) {
        int []arr=new int[]{1,2,3,4,5};
        System.out.println(Arrays.toString(arr));

    }
}

在这里插入图片描述

此种调用方法相当于引入了util包中的所以类,但是存在一个隐患:
不同包中的类的类名是可以相同的,如果采用了这种调用方式,引用了两个包时,
如果这两个包中有类名相同的两个类,此时编译器无法识别调用的类究竟是谁!

举例:

import java.util.Date;

public class Test {
    public static void main(String[] args) {
        Date data1 = new Date();
        java.sql.Date  data2  = new java.sql.Date(10);
    }
}

代码分析:

在上述代码中,util 包中与sql 包中均有一个名为Data的类,分别从不同的方式导包,引用Data类,则编译器不会报错。

而如果同时采用第三种方式导包则会出现无法识别的情况:
在这里插入图片描述

总结:
在三种导包方式中,推荐使用第一种方式,使用哪个类,就调用哪个类。
我们在操作时是不需要去查找类所在的路径的,输入类的名称时,编译器会报提示:
在这里插入图片描述

选择对应的类之后,系统会自动添加上导入语句:

在这里插入图片描述

导入外部包中类的静态方法与静态字段

导入外部类中的静态方法的语句:

import  static 类所在的路径 .* ;

举例:
比如我们要调用Math类中的sqrt静态方法 。
在这里插入图片描述

import static java.lang.Math.*;                      // 1
public class Test2 {                                 // 2
    public static void main(String[] args) {         // 3
        double  x= 30;                               // 4
        double y =20;                                // 5
        double ret =sqrt(5);                         // 6
        System.out.println(ret);                     // 7
    }
}

在第六行代码中,可以看到sqrt方法没有类名的前缀,而直接被调用。

此import语句的作用即可调动此类下的所有的静态方法与静态字段(静态成员变量)。

不建议使用此import语句调用静态方法与静态成员字段(此import语句编译器不会自动添加上,且没有类名的前缀,代码表现起来有些奇怪)

我们还是可以通过当前类引用其他的类的import语句的第一种方法来实现。

import java.util.Arrays;
//import static java.lang.Math.*;
public class Test2 {
    public static void main(String[] args) {
        double  x= 30;
        double y =20;
        double ret =Math.sqrt(5);
        System.out.println(ret);
    }
}

在这里插入图片描述

代码分析
当我们写完Math.sqrt方法后,为什么编译器没有添加上相应的import语句呢?
原因:对于java.lang的包,系统从JDK 1.1 后自动导入,所以我们看不见导入语句。

对于java提供的包:

在这里插入图片描述

1.8 访问修饰限定符

访问修饰限定符的功能:在类,成员变量,成员方法之前加上限定符,使得类,成员变量,成员方法
在调用时(对于类则是new一个新的对象,对于成员变量则是通过对象的引用,对于成员方法亦是通过对象的引用)
就会受调用时,所在包,类的限制,
比如private修饰的成员变量只能在本类中通过对象进行引用,在其他类中就不可以通过这种方式访问。

注意: 访问修饰限定符修饰类比较特殊,之后的博客会阐述到,这里只阐述关于成员变量与方法的访问权限。
注意: 只有类,成员变量与成员方法前可以加访问修饰限定符,但是局部变量之前不能够加访问修饰限定符。
在这里插入图片描述

在学习了包的概念之后,我们能够了解这张表中的部分内容
private:修饰的方法与成员变量是只能够在自身类中访问的,其他的类均不能访问

举例:

class Cat{
   private String name;
   private  int age ;
   private void shout(){
       System.out.println("喵喵........");
   }

    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.age =10;
        cat.shout();
    }


}

在这里插入图片描述
在这里插入图片描述

default:如果我们在方法或成员变量之前加上default修饰符就会出现:

在这里插入图片描述

这是因为当成员变量与成员方法前面没有修饰符时,就会默认设置为default访问权限,
所以我们并不需要使用default修饰符

访问本包中其他类的default访问权限的方法。

public class Test {
    public static void main(String[] args) {
        Cat cat1 = new Cat();
        cat1.shout();
    }
}
class Cat{
    String name;
    int age;
    void shout(){
        System.out.println("喵喵..........");
    }
}

protected: 对于修饰符protected,子类还没学到,以后再说。
public :修饰的成员变量,方法,类可以在任何包类中被调用!

1.9 static静态修饰符

static修饰符可以修饰成员方法,也可以修饰成员变量,但是不可以修饰局部变量!
static修饰成员变量:

假如我们要创建一些学生对象,他们的名字,年龄等信息都会存放在其所对应的堆区中,但是如果他们的某一种属性值都是相同的,比如所在学校,比如班级,此时便可以只将这类属性只开辟一个空间,所有的对象共有它,这样既节省了内存空间,又便于整体修改。

//static操作符
public class Test {
    public static void main(String[] args) {
     Student student1 = new Student();
     student1.name = "张三";
     student1.age = 10;
     student1.StuNum = "123";
     Student student2 = new Student();
        student2.name = "lisi";
        student2.age = 12;
        student2.StuNum = "12348";
       student1.grade = "1班";
        System.out.println(student2.grade);
    }
}
class Student{
    String StuNum ;
    String name;
    int age;
    static String grade;


}

在这里插入图片描述
我们给student1中的grade属性赋值,但是打印student2的grade属性,缺也打印出1班,这就是静态成员变量的特性,所以对象共用此一块空间。
在内存中结构

在这里插入图片描述

static修饰成员方法:
 静态成员方法可以直接通过类名调用,也可以通过对象调用,在本类中可以直接通过方法名调用。
public class Test {
    public static void main(String[] args) {
     Student student1 = new Student();
     student1.name = "张三";
     student1.age = 10;
     student1.StuNum = "123";
     Student student2 = new Student();
        student2.name = "lisi";
        student2.age = 12;
        student2.StuNum = "12348";
       student1.grade = "1班";
      //  System.out.println(student2.grade);
      Student.shout();
      student1.shout();
    }
}
class Student{
    String StuNum ;
    String name;
    int age;
    static String grade;
public static void shout(){
    System.out.println("哈哈");
}

    public static void main(String[] args) {
        shout();
    }
}

在这里插入图片描述

静态方法与非静态方法的相互调用?

(1)

     静态方法中不能调用其他非静态方法,因为静态方法不依赖于对象,可以由类名直接引用!
    而非静态方法依赖于对象!必须通过对象引用!

(2)

  非静态方法可以调用静态方法!因为在对象引用了非静态方法后,静态方法也可以被对象名所引用,当然类名也可以。
静态方法与非静态成员变量?
与上同理,静态方法也不能调用非静态成员变量!
静态方法与this 关键字?

注: 静态方法中不能够使用this关键字,因为this关键字本质上是形参对象,而静态方法不依赖于对象。
在这里插入图片描述
注: 但是this关键字可以调用静态方法(太神奇了!),因为this本质上是形参对象,是可以通过对象名调用静态方法的!

public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.test();
    }
}
class Dog {
    String name; 
    int age = 10;     
    
    public static void shout() {
        System.out.println("汪汪..........");
    }
    public void test (){
        this.shout();
    }

}

在这里插入图片描述

总结:

 对于静态成员变量与静态成员方法的访问,我们可以通过类名. 变量名/方法名 的方式,也可以通过
 对象名.变量名/方法名的方式。建议采用第一种方式,因为静态成员变量与方法属于类,不属于对象。
静态成员变量的初始化:

静态成员变量初始化有三种方式:
1 就地初始化!

2 通过getter与setter方法进行初始化!

3 通过构造方法!(这种方法使用较少!)

其实还有第四种。静态代码块初始化,那什么是代码块呢?

2.0 代码块

 所谓代码块即我们在程序中见到的用{ }括起来的程序,称为代码块,
代码块分为几种:普通代码块(最少用),构造(实例)代码块,静态代码块
普通代码块:
 普通代码块是定义在方法中的代码块,目的是为了区分变量作用域,这个代码块用的时候很少。
public class Test {
    public static void main(String[] args) {

    }
}
class Animal{
    String name;
    int age;
     public static String  sex;
    public void test1(){
        //普通代码块  
        {
          int a = 10;
            System.out.println(a);

        }
        System.out.println(a);

}

在这里插入图片描述

结果表明在代码块内部定义的变量a,其生命周期在出代码块后便中止了。
构造代码块(实例代码块)
//构造代码块 ——构造代码块不定义在方法中,成员方法平级
//构造代码块在实例化对象时,会执行
构造代码块的格式与普通代码块的格式相同,要注意不要搞混两种代码块
public class Test {
    public static void main(String[] args) {
            Animal animal = new Animal();

    }
}
class Animal{
    String name;
    int age;
     public static String  sex;
  //构造代码块   
    {
        this.name = "狗";
        this.age = 10;
        System.out.println("实例代码块执行了.........");

    }
    }

在这里插入图片描述

静态代码块
//前面阐述到,为静态成员变量赋值可以通过静态代码块:
//静态代码块的格式比构造代码块前面多了一个static关键字
public class Test {
    public static void main(String[] args) {
            Animal animal = new Animal();
            Animal animal1= new Animal();
    }
}
class Animal{
    String name;
    int age;
     public static String  sex;
  
  //静态代码块
  static {
         sex  =  "母";
      System.out.println("静态代码块执行了.....");

  }



}



在这里插入图片描述

从结果中我们可以看到静态代码块只被执行了一次,但是我们创建了两次对象,
原因在于:
运行程序时,java中的类只会被加载一次,之前被加载过的类,不会再重复加载了

加载的过程:
在这里插入图片描述

而静态代码块属于类,它只在类加载时进行执行,类被加载时,不一定是第一次创建对象,
也有可能是通过类名引用类中静态方法。
两种代码块(普通代码块忽略)与构造方法的执行先后顺序
public class Test {
    public static void main(String[] args) {
            Animal animal = new Animal("小黑",10);
           /*Animal animal1= new Animal();*/

    }
}
class Animal{
    String name;
    int age;
     public static String  sex;
//构造方法
  public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("执行了构造方法");
    }
    public static    void test1(){
        //普通代码块  ——普通代码块是定义在方法中的代码块,目的是为了区分变量作用域
        {
          int a = 10;
            System.out.println("执行了普通代码块");

        }
      //  System.out.println(a);

    }
    //构造代码块 ——构造代码块不定义在方法中,成员方法平级
    //构造代码块在实例化对象时,会执行
    {
        this.name = "狗";
        this.age = 10;
       System.out.println("实例代码块执行了.........");

    }
  //静态代码块
    //前面阐述到,为静态成员变量赋值可以通过静态代码块:
  static {
         sex  =  "母";
      System.out.println("静态代码块执行了.....");

  }

}

在这里插入图片描述

结果: 从结果中得知,静态方法先被执行(前提是类首次被使用)然后实例化代码块执行,最后是构造方法被执行。

问题:有时就地初始化与构造代码块会同时给一个成员变量赋不同的值,同一级的代码块也会有多个,不同级代码块会依次为成员变量赋值,此时的结果会怎样取呢?

首先明确java程序执行的流程(这次我们需要引入本地初始化成员变量):

首先我们要执行静态代码块,其次要执行实例化代码块或者本地初始化成员变量(因为两者属于同一级别)看谁在前面就先执行谁,最后执行构造方法 。

因此最终决定成员属性的是构造方法,其次是看构造代码块与本地初始化变量谁在后面(因为后面的会顶替前面的)。

举例:

public class Test {
    public static void main(String[] args) {
            Animal animal = new Animal("小黑",10);
           /*Animal animal1= new Animal();*/
        System.out.println(animal.name);
    }
}
class Animal{
    String name = "猫";
    int age;
     public static String  sex;
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("执行了构造方法");
    }
    //构造代码块 ——构造代码块不定义在方法中,成员方法平级
    //构造代码块在实例化对象时,会执行
    {
        this.name = "狗";
        this.age = 10;
       System.out.println("实例代码块执行了.........");

    }
  //静态代码块
    //前面阐述到,为静态成员变量赋值可以通过静态代码块:
  static {
         sex  =  "母";
      System.out.println("静态代码块执行了.....");

  }


}

在这里插入图片描述

举例:

public class Test {
    public static void main(String[] args) {
            Animal animal = new Animal();
           /*Animal animal1= new Animal();*/
        System.out.println(animal.name);
    }
}
class Animal{

    int age;
     public static String  sex;
    public static    void test1(){
        //普通代码块  ——普通代码块是定义在方法中的代码块,目的是为了区分变量作用域
        {
          int a = 10;
            System.out.println("执行了普通代码块");

        }
      //  System.out.println(a);

    }
 /*   public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("执行了构造方法");
    }*/
    //构造代码块 ——构造代码块不定义在方法中,成员方法平级
    //构造代码块在实例化对象时,会执行
    {
        this.name = "狗";
        this.age = 10;
       System.out.println("实例代码块执行了.........");

    }
  //静态代码块
    //前面阐述到,为静态成员变量赋值可以通过静态代码块:
  static {
         sex  =  "母";
      System.out.println("静态代码块执行了.....");

  }
    String name = "猫";


}

在这里插入图片描述

2.1 对象的打印

public class Test {


    public static void main(String[] args) {
        Student student = new Student("zhangsan",10);

        System.out.println(student);
    }
}
class Student{
    String name ;
    int age ;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

如果我们直接运行,只会打印出student中的地址:
在这里插入图片描述
进行以下操作:
暂时不需要知道原理,以后会阐述到!
在Student类中:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
就会生成:
在这里插入图片描述
再运行:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1674592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基础ArkTS组件:输入框,开关,评分条(HarmonyOS学习第三课【3.3】)

输入框组件 ArkUI开发框架提供了 2 种类型的输入框: TextInput 和 TextArea ,前者只支持单行输入,后者支持多行输入,下面我们分别做下介绍。 TextInput 子组件 无 接口 TextInput(value?:{placeholder?: ResourceStr, tex…

Echarts结课之小杨总结版

Echarts结课之小杨总结版 前言基础回顾框架sale框架代码: user框架基础代码: inventory框架基础代码: total框架基础代码: 基础设置1.标题(Title)2.图例(Legend)实现 3.工具提示(Tooltip)实现 4.X轴(X Axis) 和 Y轴(Y Axis)5.数据…

架构设计入门(Redis架构模式分析)

目录 架构为啥要设计Redis 支持的四种架构模式单机模式性能分析优点缺点 主从复制(读写分离)结构性能分析优点缺点适用场景 哨兵模式结构优点缺点应用场景 集群模式可用性和可扩展性分析单机模式主从模式哨兵模式集群模式 总结 本文主要以 Redis 为例&am…

【Python |基础入门】入门必备知识(基础各方面全覆盖)

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 🎈丠丠64-CSDN博客🎈 ✨✨ 帅哥美女们,我们共同加油!一起…

Linux —— 线程控制

Linux —— 线程控制 创建多个线程线程的优缺点优点缺点 pthread_self进程和线程的关系pthread_exit 线程等待pthread_ join线程的返回值线程分离pthread_detach 线程取消pthread_cancel pthread_t 的理解 我们今天接着来学习线程: 创建多个线程 我们可以结合以前…

图搜索算法-最短路径算法-贝尔曼-福特算法

相关文章: 数据结构–图的概念 图搜索算法 - 深度优先搜索法(DFS) 图搜索算法 - 广度优先搜索法(BFS) 图搜索算法 - 拓扑排序 图搜索算法-最短路径算法-戴克斯特拉算法 贝尔曼-福特算法(Bellman-Ford&#…

树莓派 4B putty远程连接登录显示拒绝访问,密码修改

putty显示拒绝访问 可能是树莓派的ip没有找到正确的 在下载系统镜像的时候,会提示设置wifi 这里设置的WiFi和密码需记住,主机名也需记住 可以在手机打开热点(将热点的账号和密码改为跟你设置的wifi一样的) 可以在手机后台查看…

Linux系统的第六天

昨天,学习了vim编辑工具,今天学习Linux系统的目录结构、补充命令和配置网络。 一、目录结果 1.1目录的特点 Windows和Linux: Windows中c、d、e盘,每个都是一个根系统【多根系统】;Linux中只有一个根【单根系统…

Java数据类型:基本数据类型

Java是一种强类型语言,定义变量时,必须指定数据类型。 // 变量必须指定数据类型 private String username;初学者不免有个疑问:在实际编写代码的过程中,该如何选择数据类型呢? 回答这个问题之前,先来解决…

vulhub靶机struts2环境下的s2-032(CVE-2016-3081)(远程命令执行漏洞)

影响范围 Struts 2.3.19至2.3.20.2、2.3.21至2.3.24.1和2.3.25至2.3.28 当用户提交表单数据并验证失败时,后端会将用户之前提交的参数值使用OGNL表达式%{value}进行解析,然后重新填充到对应的表单数据中。 漏洞搭建 没有特殊要求,请看 (3…

给定两点所能得到的数学关系

给定两点所能得到的数学关系 正文 正文 这里介绍一个基础问题,如果给定平面上的两个点的坐标,那么它们之间能够得到什么数学关系呢? ω arctan ⁡ y 1 − y 0 x 1 − x 0 x 1 − x 0 d cos ⁡ ω y 1 − y 0 d cos ⁡ ω d ( x 1 − x…

干部谈话考察:精准洞悉,助推成长

在组织人事管理的精细布局中,干部谈话考察扮演着举足轻重的角色。它不仅是组织深度了解干部、精准评价其表现的重要窗口,更是推动干部个人成长、优化组织人才配置的关键一环。通过深入的谈话考察,我们能够全面把握干部的思想脉搏、工作能力、…

AngularJS指令

指令分类: 1)装饰器型指令 装饰器指令的作用是为DOM添加行为,使其具有某种能力。在AngularS中,大多数内置指令属于装饰器型指令,例如ng-click(单击事件)、ng-hide/ng-show(控制DOM元素的显示和隐藏)等 2)组…

uniapp 生成安卓证书没有md5指纹怎么办?

由于最新的jdk版本对应的keystore工具无法查看到md5指纹信息 但是不代表它没有md5指纹信息,只是看不到而已 解决方案: 登录uniapp开发者后台生成安卓云端证书

SSM【Spring SpringMVC Mybatis】—— Spring(二)

如果对于Spring的一些基础理论感兴趣可见👇 SSM【Spring SpringMVC Mybatis】—— Spring(一) 目录 1、Spring中bean的作用域 1.1 语法 1.2 四个作用域 2、Spring中bean的生命周期 2.1 bean的生命周期 2.2 bean的后置处理器 2.3 添加后…

【Vue】Vue指令与生命周期以及组件化编码

目录 常用内置指令v-text与v-htmlv-text : 更新元素的 textContentv-html : 更新元素的 innerHTML注意:v-html有安全性问题!!!! v-once与v-prev-oncev-pre ref与v-cloakrefv-cloak 自定义指令案例定义语法配置对象中常…

一键批量合并视频:掌握视频剪辑技巧解析,轻松创作完美影片

在数字时代的浪潮下,视频已成为人们记录和分享生活的重要工具。然而,对于许多非专业视频编辑者来说,将多个视频片段合并成一个完整的影片却是一项复杂且耗时的任务。幸运的是,云炫AI智剪一键批量合并视频功能的出现,让…

QT切换控件布局

1、切换前垂直布局 2、切换后水平布局 3、关键代码 qDebug() << "开始切换布局";QWidget *widget centralWidget();QLayout *layout widget->layout();if(layout){while(layout->count()){QLayoutItem *item layout->takeAt(0);if(item->layout…

自动化神器Autolt,让你不再重复工作!

随着互联网不断发展&#xff0c;它给我们带来便利的同时&#xff0c;也带来了枯燥、重复、机械的重复工作。今天&#xff0c;我要和大家分享一款老牌实用的自动化工具&#xff1a;AutoIt&#xff0c;它能够让你告别繁琐的重复性工作&#xff0c;提高工作效率。 这里透露一下&am…

C++中的complex

在 C 中&#xff0c;std::complex 是一个模板类&#xff0c;用于表示和操作复数。这个类是标准模板库&#xff08;STL&#xff09;的一部分&#xff0c;包含在 头文件中。std::complex 提供了一套丰富的功能&#xff0c;包括基本的算术运算、比较运算、数学函数等&#xff0c;使…