关键词搜索

源码搜索 ×
×

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

发布2019-11-01浏览508次

详情内容

一、使用 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();
        }
    }
    
      25
    • 26
    • 27
    • 28
    • 29

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

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

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

    二、使用 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();
        }
    }
    
      25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    这里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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    四、理解 main() 方法

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

    1public:表示此方法可以被外部调用
    (2static:表示此方法可以由类名称直接调用
    (3void:主方法是程序的起点,所以不需要任何的返回值
    (4)main:系统规定默认调用的方法名称,执行时默认找到 main() 方法名称
    (5)String args[]:表示运行时的参数,参数传递的形式为:“Java 类名称 参数1 参数2...
    • 1
    • 2
    • 3
    • 4
    • 5
    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]);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    五、Java 中常用的内存区域

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

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载