类和对象(两万字超详解析)(四)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 类和对象(两万字超详解析)

7.3 static修饰成员方法


一般类中的数据成员都设置为private,而成员方法设置为public,那设置之后,Student类中classRoom属性如何在类外访问呢?


public class Student{
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom = "Bit306";  //private修饰,只能在该类内部访问
// ...
}
public class TestStudent {
    public static void main(String[] args) {
        System.out.println(Student.classRoom);
    }
}
//编译失败


那static属性应该如何访问呢?

Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。


public class Student{
  // ...
  private static String classRoom = "Bit306";
  // ...
  public static String getClassRoom(){
  return classRoom;
  }
}
public class TestStudent {
  public static void main(String[] args) {
  System.out.println(Student.getClassRoom());
  }
}


输出:Bit306


【静态方法特性】


  1. 不属于某个具体的对象,是类方法
  2. 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
  3. 不能在静态方法中访问任何非静态成员变量
  4. 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用


关于第3、4点:


52ab54611b3e4ff08027182750cee5bf.png


可以看到两行代码都报错了

可以这样写:


d0e3cdc90a4d4aea8b4569c22a36014a.png


那我们要如何在静态成员内部调用非静态成员、方法呢?

我们可以new一个对象出来,通过对象名加点来调用。

还有一点: 静态方法无法重写,不能用来实现多态


7.4 static成员变量初始化


注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性。


静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。


  1. 就地初始化:

就地初始化指的是:在定义时直接给出初始值

  1. 静态代码块初始化

什么是代码块呢?请看下文


8. 代码块


8.1 代码块概念以及分类


使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:

1.普通代码块

2.构造块

3.静态块

4.同步代码块(涉及多线程部分,此处不做讲解)


8.2 普通代码块


普通代码块:定义在方法中的代码块


public class Main{
  public static void main(String[] args) {
  { 
  //直接使用{}定义,普通方法块
  int x = 10 ;
  System.out.println("x1 = " +x);
  } 
  int x = 100 ;
  System.out.println("x2 = " +x);
  }
} 
// 执行结果
  x1 = 10
  x2 = 100


8.3 构造代码块


构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。


public class Student{
    //实例成员变量
    private String name;
    private String gender;
    private int age;
    private double score;
    public Student() {
        System.out.println("I am Student init()!");
    }
    //实例代码块
    {
        this.name = "bit";
        this.age = 12;
        this.gender = "man";
        System.out.println("I am instance init()!");
    }
    public void show(){
        System.out.println("name: "+name+" age: "+age+" gender: "+gender);
    }
}
public class Main {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.show();
    }
}


输出:


cd2baf43882847509adbdeb4bdabd6df.png


可以看出,它是先调用实例代码块,再调用不带参数的构造方法。

我们再来看看加入静态代码块会怎样。


8.4 静态代码块


使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。


public class Student{
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom;
    //实例代码块
    {
        this.name = "bit";
        this.age = 12;
        this.gender = "man";
        System.out.println("I am instance init()!");
    }
    // 静态代码块
    static {
        classRoom = "bit306";
        System.out.println("I am static init()!");
    }
    public Student(){
        System.out.println("I am Student init()!");
    }
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println("=====================");
        Student s2 = new Student();
    }
}


输出:


e2ac0cb126ae4f9f85f7a5358e793c6c.png

我们可以看出:

先执行静态代码块,初始化静态的数据成员,再执行非静态代码块,初始化非静态数据成员,再执行不带参数的构造方法。而静态代码块,不论你实例化了多少对象,它只执行一次(第一次实例化时执行)。


总结:

1.静态代码块不管生成多少个对象,其只会执行一次

2.调用构造方法时,静态代码块最先执行,再是非静态代码块,最后是构造函数

3.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的

4.如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)

5.实例代码块只有在创建对象时才会执行


最后


看到这里,相信大家都有所收获,对类和对象应该没啥问题了吧,下期给大家讲解继承和多态。


相关文章
|
6天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
20 3
|
27天前
|
存储 编译器 C语言
C++类与对象深度解析(一):从抽象到实践的全面入门指南
C++类与对象深度解析(一):从抽象到实践的全面入门指南
44 8
|
27天前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
25 3
|
27天前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
43 3
|
26天前
|
Python
深入解析 Python 中的对象创建与初始化:__new__ 与 __init__ 方法
深入解析 Python 中的对象创建与初始化:__new__ 与 __init__ 方法
15 1
|
20天前
|
程序员 开发者 Python
深度解析Python中的元编程:从装饰器到自定义类创建工具
【10月更文挑战第5天】在现代软件开发中,元编程是一种高级技术,它允许程序员编写能够生成或修改其他程序的代码。这使得开发者可以更灵活地控制和扩展他们的应用逻辑。Python作为一种动态类型语言,提供了丰富的元编程特性,如装饰器、元类以及动态函数和类的创建等。本文将深入探讨这些特性,并通过具体的代码示例来展示如何有效地利用它们。
22 0
|
2月前
|
设计模式 存储 人工智能
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
149 3
|
2月前
|
JavaScript 前端开发 API
Javaweb之javascript的BOM对象的详细解析
BOM为Web开发提供了强大的API,允许开发者与浏览器进行深入的交互。合理使用BOM中的对象和方法,可以极大地增强Web应用的功能性和用户体验。需要注意的是,BOM的某些特征可能会在不同浏览器中表现不一致,因此在开发过程中需要进行仔细的测试和兼容性处理。通过掌握BOM,开发者能够制作出更丰富、更动态、更交互性的JavaWeb应用。
29 1
|
3月前
|
缓存 Java 开发者
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
40 0
Spring高手之路22——AOP切面类的封装与解析
|
3月前
|
JSON 图形学 数据格式
Json☀️ 一、认识Json是如何解析成类的
Json☀️ 一、认识Json是如何解析成类的

推荐镜像

更多