【从零开始学习JAVA | 第十二篇】static静态变量

目录

前言:

背景知识:

final修饰词:

static修饰符:

引用场景:

静态变量:

静态常量:

静态方法:

总结:


前言:

本篇开始我们就将介绍JAVA面向对象的进阶内容了,此后概念繁多且难于理解,希望我们可以做好心理准备,跟我一起征战JAVA,打好JAVA基础。

本文部分内容参考《JAVA核心技术  卷I》进行编写,这是一本很不错的书,推荐大家购买观看。

背景知识:

final修饰词:

在Java中,final关键字可以用来修饰类、方法和变量,表示它们一旦赋值就不能被修改(为常量),或一旦声明就不能被继承或重写。具体来说,它有以下用途:

  1. final修饰的变量被称为常量或者只读变量,它们一旦被赋值之后就不能再次改变值了。常量通常被使用在程序中的某些恒定值和配置信息中,常量名一般使用全大写。

  2. final修饰的方法被称为不可重写方法,子类不可以对其进行重写。可以在任何方法内对final方法进行调用,不必在被调用方法的声明中采用final关键字。

  3. final修饰的类被称为不可继承类,不能有子类继承这个类。

static修饰符:

在Java中,static是一个关键字,它可以用来修饰成员变量、方法和代码块。它所表示的含义是“静态的”,它们与类相关而不是与实例对象相关,可以在类级别上直接访问,即不需要创建对象实例。

具体来说,static有以下几个用途:

1. static修饰的变量被称为静态变量或类变量,它们只会被初始化一次,无论创建多少个对象实例,都会共享同一份静态变量。静态变量可以用类名或者对象实例来访问,但建议使用类名访问。

2. static修饰的成员方法被称为静态方法,它们与类相关而不是与对象实例相关,无法访问非静态成员。静态方法可以直接使用类名调用,也可以使用对象实例调用。

3. static代码块是一段静态代码,在类被加载时执行一次,用来初始化静态成员变量,它们只会被执行一次。

static的使用可以方便访问和操作类级别的数据,同时可以避免创建多个对象实例时出现冗余的数据。但是,由于静态变量、静态方法和静态代码块与类相关,而不是与对象实例相关,因此开发人员应该谨慎使用,避免过度使用静态成员,导致代码不易维护和扩展。

引用场景:

静态变量:

public class Example {
    private static int count = 0;  // 静态变量

    private int id;  // 实例变量

    public Example() {
        count++;  // 实例化对象时,增加count计数
        id = count;
    }

    public static int getCount() {  // 静态方法
        return count;
    }

    public int getId() {
        return id;
    }
}
public class Test {
    public static void main(String[] args) {
        Example e1 = new Example();
        Example e2 = new Example();
        Example e3 = new Example();
        System.out.println("Count: " + Example.getCount());
        System.out.println("e1 ID: " + e1.getId());
        System.out.println("e2 ID: " + e2.getId());
        System.out.println("e3 ID: " + e3.getId());
    }
}

运行结果为:

因此我们发现:静态变量并不独属于哪一个对象,它只属于类,由从类创建的每一个对象共享。

而我们在上面创建的叫做静态变量。下面我们即将为大家展示一下静态常量

静态常量:

public class Example {
    public static final int MAX_VALUE = 100;  // 声明静态常量

    private int value;  // 实例变量

    public Example(int value) {
        if (value > MAX_VALUE) {  // 检查输入的值是否超过最大值
            this.value = MAX_VALUE;  // 如果超过最大值,设置为最大值
        } else {
            this.value = value;  // 否则,使用输入的值
        } 
    }

    public int getValue() {
        return value;
    }
}
public class Test {
    public static void main(String[] args) {
        Example e1 = new Example(50);
        Example e2 = new Example(200);
        System.out.println("e1 value: " + e1.getValue());
        System.out.println("e2 value: " + e2.getValue());
    }
}

运行结果为:      

 在这我们把MAX_value设置为了一个常量,有被类中所有的对象共用,这就是静态常量。

静态方法:

在Java中,静态方法是属于类的方法,可以在类被加载时直接访问,而不需要先创建该类的实例

静态方法使用关键字static修饰,可以直接通过类名来调用,而不需要使用对象引用。静态方法可以访问类的静态变量和其他静态方法,但不能访问实例变量和实例方法。此外,静态方法不能被子类重写。

静态方法通常用于公共实用程序,例如Java内置的Math类的数学函数,就是由Math类的静态方法实现的。

以下是静态方法的一些特点:

1. 静态方法属于类,而不属于对象,因此可以直接用类名来调用。

2. 静态方法不能使用this关键字,因为它不属于对象。

3. 静态方法中不能访问非静态成员,因为非静态成员是属于对象的。

4. 静态方法可以调用其他静态方法和变量,而不需要通过对象引用。

5. 静态方法在类被加载时就会被加载到内存中,因此可以直接使用,不需要创建对象。

以下是一个静态方法的示例,该方法用于计算两个数字的和:

public class Sum {
    public static int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int result = Sum.add(5, 10); // 静态方法的调用
        System.out.println(result);
    }
}

在这个示例中,我们定义了一个名为add()的静态方法,用于计算两个整数的和。在main()方法中,我们直接使用类名Sum来调用add()方法,并将结果存储在result变量中,最后输出结果。

静态:

        起初 C 中引用关键字 static 是为了表示退出一个块代码后还会存在的一个局部变量,随后,我们又在 C  中赋予了 static 第二个意思:不能从其他文件访问的全局变量和函数。最后C++第三次重用了这个关键字,表示不属于任何类对象的变量和函数,这个关键字的含义才真正的与JAVA相等。

小拓展:

        我们在看JAVA 的底层代码的时候,有的时候会发现一个神奇的现象:为什么有的变量明明已经被修饰为final变量了,我们调用类方法还是可以对这个变量进行修改呢?

例如:我们看一看System类中的out

public static final PrintStream out = null;

这是System类中的一个静态常量(out),它全局保存了标准输出流(System.out),是一个PrintStream类型的常量。在Java中,PrintStream是用于输出各种数据类型数据的输出流,可以将输出的数据转换成字节流。在默认情况下,out变量指向的是一个PrintStream对象,它将数据输出到控制台。当我们使用System.out.println()方法时,实际上就是向out输出流中写入数据。

但是我们可以调用类函数System.setOut();对这个静态常量进行修改,更改他的流向

我们在这里就把一个默认数据流向控制台的类更改了流向,让其流向自建文件中。

import java.io.*;

public class RedirectOutputStream {
    public static void main(String[] args) {
        try {
            FileOutputStream fos = new FileOutputStream("output.txt");
            PrintStream ps = new PrintStream(fos);
            System.setOut(ps); // 将System.out重定向到文件输出流
            System.out.println("Hello, world!"); // 输出到文件
            System.out.close(); // 关闭输出流
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

那么为什么呢?为什么setOut函数可以实现对一个final常量更改呢?

解释:setOut的实现方式并不是以JAVA语言实现的,她是原生方法,由C和C++编写,因此不受JAVA的语法限制,自然也就可以对一个静态常量进行更改。

总结:

static是JAVA中在类上很常见的一个关键字,他赋予了类一些很特殊的功能,例如共享变量,可以通过类直接访问等等,是一个比较重要的关键字,因此我们要学好这样一篇,学好static关键字。

 如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

猜你喜欢

转载自blog.csdn.net/fckbb/article/details/131294022