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 +
                '}';
    }
}
目录
相关文章
|
15天前
|
Java
Java基础—笔记—static篇
`static`关键字用于声明静态变量和方法,在类加载时初始化,只有一份共享内存。静态变量可通过类名或对象访问,但推荐使用类名。静态方法无`this`,不能访问实例成员,常用于工具类。静态代码块在类加载时执行一次,用于初始化静态成员。
10 0
|
19天前
|
设计模式 安全 Java
Java并发编程实战:使用synchronized关键字实现线程安全
【4月更文挑战第6天】Java中的`synchronized`关键字用于处理多线程并发,确保共享资源的线程安全。它可以修饰方法或代码块,实现互斥访问。当用于方法时,锁定对象实例或类对象;用于代码块时,锁定指定对象。过度使用可能导致性能问题,应注意避免锁持有时间过长、死锁,并考虑使用`java.util.concurrent`包中的高级工具。正确理解和使用`synchronized`是编写线程安全程序的关键。
|
1天前
|
安全 Java 编译器
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
本文简要介绍了Java中的`synchronized`关键字,它是用于保证多线程环境下的同步,解决原子性、可见性和顺序性问题。从JDK1.6开始,synchronized进行了优化,性能得到提升,现在仍可在项目中使用。synchronized有三种用法:修饰实例方法、静态方法和代码块。文章还讨论了synchronized修饰代码块的锁对象、静态与非静态方法调用的互斥性,以及构造方法不能被同步修饰。此外,通过反汇编展示了`synchronized`在方法和代码块上的底层实现,涉及ObjectMonitor和monitorenter/monitorexit指令。
6 0
|
1天前
|
Java
两千字讲明白java中instanceof关键字的使用!
两千字讲明白java中instanceof关键字的使用!
4 0
|
1天前
|
Java 开发者
Java基础知识整理,注释、关键字、运算符
在日常的工作中,总会遇到很多大段的代码,逻辑复杂,看得人云山雾绕,这时候若能言简意赅的加上注释,会让阅读者豁然开朗,这就是注释的魅力!
36 11
|
6天前
|
安全 Java 开发者
Java并发编程:深入理解Synchronized关键字
【4月更文挑战第19天】 在Java多线程编程中,为了确保数据的一致性和线程安全,我们经常需要使用到同步机制。其中,`synchronized`关键字是最为常见的一种方式,它能够保证在同一时刻只有一个线程可以访问某个对象的特定代码段。本文将深入探讨`synchronized`关键字的原理、用法以及性能影响,并通过具体示例来展示如何在Java程序中有效地应用这一技术。
|
10天前
|
Java
Java关键字(1)
Java关键字(1)
|
1月前
|
安全 Java 编译器
Java 中的关键字
Java 中的关键字
75 0
|
1月前
|
存储 Java
【Java】深入理解Java中的static关键字
【Java】深入理解Java中的static关键字
25 0