Java的static关键字

简介: Java的static关键字

关键字:static


@[toc]


基本认识

  • 当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上 的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象, 其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少 对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个 国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中 都单独分配一个用于代表国家名称的变量。
  • static:静态的
  • static可以用来修饰:属性、方法、代码块、内部类
  • 使用static修饰属性:静态变量(类变量)

static修饰属性

1.1、属性,按是否使用static修饰,又分为静态属性和非静态属性(实例变量)

  • 实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,
    当修改其中一个对象的非静态属性时,不会导致其他对象中同样的属性值的修改
  • 静态变量:我们创建了类的多个对象,多个对象共享一个静态变量。
    当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的

1.2、static修饰属性的其他说明:

  • 静态变量随着类的加载而加载。可以通过“类.静态变量”的方式进行调用
  • 静态变量的加载要早于对象的创建
  • 由于类只会加载一次,则静态变量在内存中也只会存在一份,存在方法区的静态域中
  • 调用关系
类变量(静态变量) 实例变量
yes no
对象 yes yes

1.3、静态属性举例:Sysyem.out、Math.PI

1.4、类变量 vs 实例变量内存解析

在这里插入图片描述


使用static修饰方法

  • 随着类的加载而加载,可以通过”类.静态方法“进行调用
类方法(静态方法) 非静态方法
yes no
对象 yes yes
  • 静态方法中,只能调用静态的方法或属性
  • 非静态方法中,即可以调用静态方法和属性,也可以调用静态的方法和属性(以上两点都源自于他们的生命周期)

ps:粗暴理解来说,就是静态的先加载,随着类的加载就已经,无论方法还是属性,静态的不一定可以掉用非静态的,因为这时候非静态的还没加载但是静态的以经随着类加载了,但是非静态的一定可以调用静态的,因为非静态是随着对象而加载,当加载对象之后,静态的早就加载好了,所以可以调用静态的,不要死记硬背,从生命周期的角度去理解,类的声明周期和对象的生命周期

  • static注意点:在静态的方法内,不能使用this关键字、super关键字

开发中去判别使用static

开发中,如何确定一个属性是否要声明为static?
  • 这个属性可以被多个对象所共享的,这个属性不会随着对象的不同而不同
  • 类中的常量也常常声明static(例如圆周率PI)
开发中,如何确定一个方法是否要声明为static?
  • 操作静态属性的方法通常设置为静态
  • 工具类中的方法,习惯上声明为static的。比如说:Math、Arrays、Collections

在这里插入图片描述


前面几点代码详解:

以上几点看完了可以看代码来理解

package day1.java1;

public class StaticTest {
    public static void main(String[] args) {
        Chinese.nation = "中国";//静态变量随着类的加载而加载,静态变量的加载要早于对象的创建
        Chinese c1 = new Chinese();
        c1.name = "小明";
        c1.age = 12;

        Chinese c2 = new Chinese();
        c2.name = "小红";
        c2.age = 13;

        c1.nation = "china";

        //static修饰方法

        //通过对象调用方法
        c1.eat();
        //通过类进行调用
        Chinese.show();
        //类调用非静态方法会编译不通过
//        Chinese.eat();


    }
}

//中国人
class Chinese {
    String name;
    int age;
    static String nation;//静态属性

    public void eat() {//非静态方法
        System.out.println("吃饭");
    }

    public static void show() {//随着类的加载而加载
        System.out.println("我是一个中国人");
        //不能调用非静态结构
//        eat();
//        name="tom";
        //可以调用静态的结构
        System.out.println(Chinese.nation);//这里的Chinese可以省略
    }

    public static void walk() {//静态方法

    }

static关键字的应用举例

(结合代码和注释一起看)

package day1.java1;

//static关键字的应用
public class LxtCircleTest {
    public static void main(String[] args) {
        Circle c1 = new Circle();
        Circle c2 = new Circle();
        Circle c3 = new Circle(3.4);//调用第二个构造器
        System.out.println("c1的id:"+c1.getId());//1
        System.out.println("c2的id:"+c2.getId());//2
        System.out.println("c3的id:"+c3.getId());//3

        System.out.println("创建圆的个数:"+Circle.getTotal());
    }
}

class Circle {
    private double radius;//半径
    private int id;//编号,自动赋值

    public Circle() {//构造器给它一个赋值操作
        id = init++;//这里的init属性加了static,内存之中只有1份init,所以没用一次构造器就会增加一次
        total++;//
    }

    //给radius赋值
    public Circle(double radius){
        this();//可以在类的构造器中使用"this(形参列表)"的方式,调用本类中重载的其他的构造器
        //  id = init++
        //  total++;//上面的this();相当于调用了这里注释了的代码,因为可能调用不同的构造器,所以这个构造器也需要去进行init和total的增加
        this.radius=radius;
    }

    private static int total;//记录圆的个数(造了几个圆的对象)
    //希望id是自动赋值,从1开始
    private static int init = 1;//多个对象共享,static声明的属性被所有对象共享,

    public double findArea() {//求圆的面积
        return Math.PI * radius * radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public static int getTotal() {//生成的get方法自动变成static,因为一个属性是static,通常操作这个属性的方法也是static
        return total;
    }
}

static练习题:账户信息

题目:编写一个类实现银行账户的概念,包含的属性有“帐号”、“密 码”、“存款余额”、“利率”、“最小余额”,定义封装这些 属性的方法。账号要自动生成。 编写主类,使用银行账户类,输入、输出3个储户的上述信息。 考虑:哪些属性可以设计成static属性。

答案代码:

测试类AccountTest

package day1.LXT;

public class AccountTest {
    public static void main(String[] args) {
        Account a1 = new Account();//建立账户1
        Account a2 = new Account("000000",10000);//建立账户2

        Account.setRate(0.02);
        Account.setMinMoney(100);
        //输出
        System.out.println(a1.toString());//这里的toString方法可以省略
        System.out.println(a2.toString());

        System.out.println(a1.getRate());
        System.out.println(a2.getMinMoney());


    }
}

Account类

package day1.LXT;
/*编写一个类实现银行账户的概念,包含的属性有“帐号”、“密
        码”、“存款余额”、“利率”、“最小余额”,定义封装这些
        属性的方法。账号要自动生成。
        编写主类,使用银行账户类,输入、输出3个储户的上述信息。
        考虑:哪些属性可以设计成static属性。
*/
public class Account {
    private int id;//账号(也自动生成)
    private String password;//密码
    private double money;//余额

    private static double rate;//利率
    private static double minMoney;//最小余额
    //用于自动生成id
    private static int init=1;
//构造器
    public Account(){
        id=init++;
    }

    public Account(String password,double money){
        this();
        this.password=password;
        this.money=money;

    }



    //get和set方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String passwor) {
        this.password = passwor;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public static double getRate() {
        return rate;
    }

    public static void setRate(double rate) {
        Account.rate = rate;
    }

    public static double getMinMoney() {
        return minMoney;
    }

    public static void setMinMoney(double minMoney) {
        Account.minMoney = minMoney;
    }

    @Override//重写toSting来输出用户属性
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", password=" + password +
                ", money=" + money +
                '}';
    }
}
id setMinMoney(double minMoney) {
        Account.minMoney = minMoney;
    }

    @Override//重写toSting来输出用户属性
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", password=" + password +
                ", money=" + money +
                '}';
    }
}
目录
相关文章
|
24天前
|
存储 Java
Java 中的静态(static)
【10月更文挑战第15天】静态是 Java 语言中一个非常重要的特性,它为我们提供了一种方便、高效的方式来管理和共享资源。然而,在使用过程中,我们需要谨慎考虑其优缺点,以确保代码的质量和可维护性。
|
1月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
28 3
|
1月前
|
Java 编译器
在Java中,关于final、static关键字与方法的重写和继承【易错点】
在Java中,关于final、static关键字与方法的重写和继承【易错点】
23 5
|
1月前
|
Java
Java关键字 —— static 与 final 详细解释!一看就懂 有代码实例运行!
这篇文章详细解释了Java中static和final关键字的用法,包括它们修饰类、方法、变量和代码块时的行为,并通过代码示例展示了它们的具体应用。
195 0
Java关键字 —— static 与 final 详细解释!一看就懂 有代码实例运行!
|
2月前
|
存储 Java
Java之静态(static)与实例(instance)
Java之静态(static)与实例(instance)
|
3月前
|
Java
【Java基础面试四十一】、说一说你对static关键字的理解
这篇文章主要介绍了Java中static关键字的概念和使用规则,强调了类成员与实例成员的区别及其作用域的限制。
|
3月前
|
存储 Java 对象存储
【Java基础面试四十三】、 static和final有什么区别?
由于网络原因,我无法获取到您提供的链接内容。如果需要我解析该网页,请确保链接有效并重试,或者提供其他问题,我会尽力帮助您。
|
3月前
|
Java
【Java基础面试四十二】、 static修饰的类能不能被继承?
这篇文章讨论了Java中static关键字修饰的类是否可以被继承,解释了静态内部类的概念、规则以及如何实例化。
|
3月前
|
Java
【Java】static 类方法中注意事项
【Java】static 类方法中注意事项
|
3月前
|
Java
【Java】static 修饰成员方法
【Java】static 修饰成员方法