一篇文章带你搞定 Java 中的 static 关键字

一、使用 static 声明属性

如果在程序中使用 static 声明属性的话,则此属性称为全局属性(或者静态属性)

class Person{
    String name;
    int age;
    String country = "A city"; // 定义城市属性,具有默认值
    public Person(String name,int age){ //通过构造方法设置 name 和 age
        this.name = name;
        this.age = age;
    }
    public void info(){
        System.out.println("name:" + this.name + "\tage:" + this.age + "\tcity:" + this.country);
    }
}

public class Test{
    public static void main(String[] args) {
        Person p1 = new Person("J1",30);
        Person p2 = new Person("J2",31);
        Person p3 = new Person("J3",32);
        p1.info();
        p2.info();
        p3.info();

    }
}

这里定义了 country 属性,赋予了 3 个对象,如果现在想要更改这些对象的country属性,则需要一个一个的修改,费时费力。

可以将country 属性使用 static 进行声明为公共属性

class Person{
    String name;
    int age;
    static String country = "A city"; // 定义城市属性,具有默认值
    public Person(String name,int age){ //通过构造方法设置 name 和 age
        this.name = name;
        this.age = age;
    }
    public void info(){
        System.out.println("name:" + this.name + "  age:" + this.age + "  city:" + this.country);
    }
}

public class Test{
    public static void main(String[] args) {
        Person p1 = new Person("J1",30);
        Person p2 = new Person("J2",31);
        Person p3 = new Person("J3",32);
        System.out.println("--------修改之前--------");
        p1.info();
        p2.info();
        p3.info();
        System.out.println("--------修改之后--------");
        p1.country = "B city";
        p1.info();
        p2.info();
        p3.info();
    }
}

在这里插入图片描述
这里只修改了一个对象的城市属性,然而全部的对象的城市内容都发生了变化,说明使用 static 声明的属性时所有对象共享的。

示例 static 属性保存的内存分配图
在这里插入图片描述
这里存在一个问题,一个类中的公共属性由一个对象修改了,这样明显不合适,应该由类进行修改,所以上面代码在访问 static 属性时最好可以用类名称直接调用,因此也可以把使用 static 声明的属性称为类属性

类名称.static 属性
示例:
Person.country = "B city";

二、使用 static 声明方法

static 既可以在声明属性的时候使用,也可以用其来声明方法,用它声明的方法有时也被称为“类方法”。

class Person{
    String name;
    int age;
    private static String country = "A city"; // 定义城市属性,具有默认值
    public static void setCountry(String c){ // 使用 static 声明方法
        country = c;
    }
    public static String getCountry(){
        return country;
    }
    public Person(String name,int age){ //通过构造方法设置 name 和 age
        this.name = name;
        this.age = age;
    }
    public void info(){
        System.out.println("name:" + this.name + "  age:" + this.age + "  city:" + this.country);
    }
}

public class Test{
    public static void main(String[] args) {
        Person p1 = new Person("J1",30);
        Person p2 = new Person("J2",31);
        Person p3 = new Person("J3",32);
        System.out.println("--------修改之前--------");
        p1.info();
        p2.info();
        p3.info();
        System.out.println("--------修改之后--------");
        Person.setCountry("B city");
        p1.info();
        p2.info();
        p3.info();
    }
}

这里Person 类将 country属性进行了封装,所以想要设置此属性就必须使用 setter() 方法,但是这里方法是使用 static 声明的,所以可以直接使用类名称调用

在实际的开发之中,如果要定义一个类中的方法,一般都会以非 static 方法(普通方法)为主,而定义为static一般只有一种情况:此方法不希望通过实例化对象进行调用,则此时就会有两种因素
(1)本类没有提供普通属性,这样产生实例化对象没有意义;
(2)本类无法直接进行对象实例化,只能够利用 static 操作;

需要注意非 static 声明的方法可以去调用 static 声明的属性或方法,但是static 声明的方法是不能调用非 static 类型声明的属性或方法的

在这里插入图片描述
因为在程序中所有的属性和方法必须在对象开辟堆内存之后才可以调用,而 static 类型的方法在对象未被实例化时候就可以被类名所调用

static 方法中不会存在 this,因为不能在静态方法中调用非静态方法

三、static 的相关应用

我们已经知道,static 属性是所有对象共享的,那么就可以使用 static 属性统计一个类到底产生了多少个实例化对象

class Demo{
  private static int count = 0;
  public Demo(){ // 只要有对象产生就应该自增
      count++;
      System.out.println("产生了 " + count + " 个对象!");
  }
}

public class Exercise {
    public static void main(String[] args) {
        new Demo();
        new Demo();
        new Demo();
    }
}

在这里插入图片描述

四、理解 main() 方法

之前一直使用 main() 方法的定义中,一直有 static 关键字的存在,那么 main() 方法每个参数的具体含义是什么?

1public:表示此方法可以被外部调用
(2static:表示此方法可以由类名称直接调用
(3void:主方法是程序的起点,所以不需要任何的返回值
(4)main:系统规定默认调用的方法名称,执行时默认找到 main() 方法名称
(5)String args[]:表示运行时的参数,参数传递的形式为:“Java 类名称 参数1 参数2...
public class Exercise {
    public static void main(String[] args) {
        if(args.length!=3){
             System.out.println("输入的参数小于 3 个!");
            System.exit(1); //表示系统推出,只要在 exit() 方法中设置一个非零的数字即可
        }
        for (int x=0;x<args.length;x++){
            System.out.println("第" + (x+1) + "个参数:" + args[x]);
        }
    }
}

如果一个方法可以由主方法直接调用,则必须按照“public static 方法的返回值类型”,因为主方法是静态方法,而静态方法是不能调用非静态方法的,所以之前的方法声明处才必须加上 static 关键字

五、Java 中常用的内存区域

(1)栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
(2)堆内存空间:保存每个对象的具体属性内容。
(3)全局数据区:保存static 类型的属性
(4)全局代码区:保存所有的方法定义

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南淮北安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值