Java静态类

静态类

静态方法与非静态方法之间的区别

Java是面向对象的,但若处于某种特殊的情况下,通常是实用的方法,则不需要类的实例,static这个关键词可以标记出不需实例的方法,一个静态的方法代表说"一种不依靠实例也不需要对象的行为"

非静态方法(需要实例对象)

public class Song {
    String title;
    public Song(String t) {
        title = t;
    }
    public void play() {
        SoundPlayer player = new SoundPlayer();
        player.playSound(title);
    }
}

静态方法(以Math方法为例)

进入Math源码发现大部分的方法都是为static 方法

image-20211220204842408

所以我们在使用Math方法的时候,都是使用Math直接点上方法,而不用去创建Math实例对象

以类的名称调用静态的方法

以引用变量的名称调用非静态的方法

静态方法不能调用非静态的变量

如果你尝试在静态的方法内使用实例变量,编译器会认为:“不知道你说的是那个实例的变量!” 静态的方法是不知道堆上有那些实例的。

public class test01 {
    private int size;

    public static void main(String[] args) {
        System.out.println("Size of duck is" + size); // 此时我们根本无从知道堆上是否有Duck
    }

    public void setSize(int s) {
        size = s;
    }

    public int getSize() {
        return size;
    }
}

运行上述代码会报错

image-20211220205548974

静态的方法也不可以调用非静态的方法

public class test01 {
    private int size;

    public static void main(String[] args) {
        System.out.println("Size of duck is" + getSize());
    }

    public void setSize(int s) {
        size = s;
    }

    public int getSize() {
        return size;
    }
}

image-20211220205736819

静态方法无法看到实例的状态

静态变量:它的值对所有的实例来说都相同

class Duck {
    int duckCount = 0;
    public Duck() {
        duckCount++;
    }
}

这样来计算duck的数量显然是不可以的,因为每个实例对象的duckCount的初始值都是0。

public class test01 {
    private int size;
    private static int duckCount = 0;

    public test01(int size) {
        duckCount++;
    }

    public void setSize(int s) {
        size = s;
    }

    public int getSize() {
        return size;
    }
}

使用静态变量duckCount只有在第一次在被载入的时候初始化,每次构造函数的时候,此变量就会递增

 public static void main(String[] args) {
        test01 test01 = new test01();
        System.out.println(duckCount);
        test01 test02 = new test01();
        System.out.println(duckCount);
        test01 test03 = new test01();
        System.out.println(duckCount);
}

image-20211220210653266

静态变量是共享的。同一个类所有的实例共享一份静态变量

每个变量:每个实例一个

静态变量:每个一个

静态变量的起始动作

静态项目的初始化有两项保证:

  • 静态变量会在该类的任何对象创建之前就完成初始化,
  • 静态变量会在该类的静态方法执行之前就初始化。

静态变量会在任何静态方法执行前前初始化完成

class Player {
    static int playerCount = 0; // 载入的时候会被初始化成0
    private String name;

    public Player(String name) {
        this.name = name;
        playerCount++;
    }
}
class PlayerTestDrive {
    public static void main(String[] args) {
        System.out.println(Player.playerCount);
        Player one = new Player("Tiger Woods");
        System.out.println(Player.playerCount); // 静态变量也是通过类的名称来存取的
    }
}

image-20211220211603190

静态的final变量是常数

我们以Math.PI为例

public static final double PI = 3.141592653589793;
  • 此处被标记为public,因此可以供各方读取
  • 此变量被标记为static,所以你不需要Math的实例
  • 此处被标记为final,因为圆周率是不变的
  • 此外没有别的方法可以识别变量为不变的常数(constant),但有命名惯例(naming convention)可以帮助你认出来
    常数变量的名称应该都是大写字母

静态初始化程序(static initializer)是一段在加载类是会执行的程序代码,它会在其他程序可以使用该类之前就执行,所以很适合放静态final变量的起始程序

class Foo {
    final static int x;
    static {
        x = 42;
    }
}
静态final变量的初始化

①声明的时候:

public class Foo {
    public static final int FOO_X = 25;
}

②在静态初始化程序中:

public class Bar {
    public static final double BAR_SIGN;
    static { // 这段代码会在类被加载的时候执行
        BAR_SIGN = (double) Math.random();
    }
}

如果没有用这两种方法之一来给值的话,编译器会告诉你,你没有初始化;

final不知用在静态变量上
  • final的变量代表你不能改变它的值
  • final的方法代表你不能覆盖掉此方法
  • final的类代表你不能继承该类(也就是创建子类)

静态类的问题

  • 非静态方法可以调用该类的静态变量和静态方法
  • 将类标记为final的目的主要是为了安全
  • 如果类已经被标记为final的,再标记final的方法会变得很多余,因为类无法被子类继承,所有的方法都不会被覆盖,如果只是想限定某些方法不被重写,只要在个别方法上加上final就可以了

要点!!!!

  • 静态的方法应该用类的名称来调用,而不是用对象引用变量

  • 静态的方法可以直接调用而不需要在堆上的实例。

  • 静态的方法是一个非常实用的方法,它不需要特别的实例变量值

  • 静态的方法不能存取非静态的方法

  • 如果类只有静态方法,你可以将构造函数标记为private的以避免被初始化

  • 静态变量为该变量所属类的成员共享.静态变量只有一份,而不是每个实例都有自己的一份

  • 静态方法可以存取静态变量

  • 在Java中常量是把变量同时标记为static和final的

  • final的静态变量值必须在声明或静态初始化程序中赋值:

    static {
        DOG_CODE = 420;
    }
    
  • 常量的命名习惯是全部使用大写字母

  • final值一旦被赋值,就不能更改

  • final的方法不能被覆盖

初始化

  • 静态变量为该变量所属类的成员共享.静态变量只有一份,而不是每个实例都有自己的一份

  • 静态方法可以存取静态变量

  • 在Java中常量是把变量同时标记为static和final的

  • final的静态变量值必须在声明或静态初始化程序中赋值:

    static {
        DOG_CODE = 420;
    }
    
  • 常量的命名习惯是全部使用大写字母

  • final值一旦被赋值,就不能更改

  • final的方法不能被覆盖

  • final的类不能被继承

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值