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 +
                '}';
    }
}
目录
相关文章
|
11天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
12天前
|
缓存 安全 Java
Java volatile关键字:你真的懂了吗?
`volatile` 是 Java 中的轻量级同步机制,主要用于保证多线程环境下共享变量的可见性和防止指令重排。它确保一个线程对 `volatile` 变量的修改能立即被其他线程看到,但不能保证原子性。典型应用场景包括状态标记、双重检查锁定和安全发布对象等。`volatile` 适用于布尔型、字节型等简单类型及引用类型,不适用于 `long` 和 `double` 类型。与 `synchronized` 不同,`volatile` 不提供互斥性,因此在需要互斥的场景下不能替代 `synchronized`。
2103 3
|
2月前
|
JavaScript 前端开发 Java
java中的this关键字
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。自学前端2年半,正向全栈进发。若我的文章对你有帮助,欢迎关注,持续更新中!🎉🎉🎉
56 9
|
2月前
|
设计模式 JavaScript 前端开发
java中的static关键字
欢迎来到瑞雨溪的博客,博主是一名热爱JavaScript和Vue的大一学生,致力于全栈开发。如果你从我的文章中受益,欢迎关注我,将持续分享更多优质内容。你的支持是我前进的动力!🎉🎉🎉
56 8
|
2月前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
49 4
|
2月前
|
存储 Java
Java 中的静态(static)
【10月更文挑战第15天】静态是 Java 语言中一个非常重要的特性,它为我们提供了一种方便、高效的方式来管理和共享资源。然而,在使用过程中,我们需要谨慎考虑其优缺点,以确保代码的质量和可维护性。
|
3月前
|
Java 程序员
在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。
【10月更文挑战第13天】在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。本文介绍了Java关键字的基本概念及其重要性,并通过定义类和对象、控制流程、访问修饰符等示例,展示了关键字的实际应用。掌握这些关键字,是成为优秀Java程序员的基础。
37 3
|
3月前
|
算法 Java
在Java编程中,关键字和保留字是基础且重要的组成部分,正确理解和使用它们
【10月更文挑战第13天】在Java编程中,关键字和保留字是基础且重要的组成部分。正确理解和使用它们,如class、int、for、while等,不仅能够避免语法错误,还能提升代码的可读性和执行效率。本指南将通过解答常见问题,帮助你掌握Java关键字的正确使用方法,以及如何避免误用保留字,使你的代码更加高效流畅。
46 3
|
3月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
43 3
|
3月前
|
存储 安全 Java
了解final关键字在Java并发编程领域的作用吗?
在Java并发编程中,`final`关键字不仅用于修饰变量、方法和类,还在多线程环境中确保对象状态的可见性和不变性。本文深入探讨了`final`关键字的作用,特别是其在final域重排序规则中的应用,以及如何防止对象的“部分创建”问题,确保线程安全。通过具体示例,文章详细解析了final域的写入和读取操作的重排序规则,以及这些规则在不同处理器上的实现差异。
了解final关键字在Java并发编程领域的作用吗?