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

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

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.实例代码块只有在创建对象时才会执行


最后


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


相关文章
|
2天前
|
缓存 开发者 索引
深入解析 `org.elasticsearch.action.search.SearchRequest` 类
深入解析 `org.elasticsearch.action.search.SearchRequest` 类
8 0
|
17天前
|
存储 安全 Java
滚雪球学Java(60):深入解析Java中的Vector集合类!
【6月更文挑战第14天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
151 59
滚雪球学Java(60):深入解析Java中的Vector集合类!
|
21天前
|
SQL 缓存 算法
【源码解析】Pandas PandasObject类详解的学习与实践
【源码解析】Pandas PandasObject类详解的学习与实践
|
13天前
|
JavaScript 前端开发 Java
【JavaScript】ECMAS6(ES6)新特性概览(二):解构赋值、扩展与收集、class类全面解析
【JavaScript】ECMAS6(ES6)新特性概览(二):解构赋值、扩展与收集、class类全面解析
16 2
|
13天前
|
存储 JavaScript 前端开发
【JavaScript】JavaScript 中的 Class 类:全面解析
【JavaScript】JavaScript 中的 Class 类:全面解析
17 1
|
13天前
|
消息中间件 监控 安全
深入解析Linux命令ipcmk:IPC对象管理新视角
`ipcmk`非标准Linux命令,假设的IPC对象创建工具,用于演示如何管理消息队列、信号量和共享内存。虽无此命令,但理解其概念有助于掌握IPC管理。例如,创建命名消息队列`my_mq`,最大1000消息,可模拟使用`ipcmk -t mq -n my_mq -q 1000`。实际操作中,应根据需求选择合适IPC机制,设置安全权限,监控使用并及时清理。
|
13天前
|
Java
【Java】Object类简单解析
【Java】Object类简单解析
15 1
|
21天前
|
存储 SQL 算法
【源码解析】深入解析 pandas的Block 类中算术运算和重排实现
【源码解析】深入解析 pandas的Block 类中算术运算和重排实现
|
3天前
|
存储 缓存 Java
Java对象内存布局深度解析
Java对象内存布局深度解析
8 0
|
4天前
|
缓存 算法 Java
提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)
提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)

推荐镜像

更多