static关键字

文章介绍了Java中的static关键字,用于修饰成员变量和方法,使得它们在所有对象间共享。static变量存储于方法区,随着类的加载而加载,可通过类名直接访问。文章通过示例代码展示了static变量如何在内存中分配,以及与非静态成员变量的区别。同时,讨论了main方法的格式,强调其public、static、void及String[]args参数的特点。
摘要由CSDN通过智能技术生成

目录

一个例子引出static关键字

static关键字

static在内存中的解释

静态变量与成员变量的区别

main方法的格式讲解


一个例子引出static关键字

class Human {
    //姓名
    private String name;
    //年龄
    private int age;
    //国籍
//    private String country;
    private static String country;

    public Human() {
    }

    public Human(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Human(String name, int age, String country) {
        this.name = name;
        this.age = age;
        this.country = country;
    }
    
    public void setCountry(String country) {
        Human.country = country;
    }

    public void show() {
        System.out.println("姓名:" + name + ",年龄:" + age + ",国籍:" + country);
    }
}

public class HumanDemo {
    public static void main(String[] args) {
        //创建第一个对象
        Human h1 = new Human("张杰", 42, "中国");
        h1.show();

        //创建第二个对象
        Human h2 = new Human("彭于晏", 38);
        h2.show();

        //创建第三个对象
        Human h3 = new Human("蔡徐坤", 22);
        h3.show();

        h3.setCountry("加拿大");
        h1.show();
        h2.show();
        h3.show();
    }
}

我们定义完并使用后发现,姓名和年龄不一样的,我们可以理解。但是我们选的几个人的国籍都是中国,这样我们每次在创建的时候,都会在堆内存中开辟这样的成员变量的内存空间。这样就造成了内存浪费。

针对于多个对象有着共同的成员变量,值是一样的情况,java就提供了一个关键字给我们使用——static关键字

static关键字

1.static关键字特点:可以修饰成员变量和成员方法

1)随着类的加载而加载

2)优先于对象而存在

3)被类的所有对象共享(举例:所有中国人的国籍信息都是一样的)

4)可以通过类名调用(一般情况下,只要我们看到一个类中有静态修饰的成员变量或者成员方法,一律推荐使用 类名.静态成员 这种方式去使用)

注:静态修饰的内容我们一般称之为类成员,与类相关的

class Student2 {
    //非静态的成员变量
    int num = 20;

    //静态的成员变量
    static int num2 = 30;
}

public class StaticDemo1 {
    public static void main(String[] args) {
        Student2 s1 = new Student2();
        System.out.println(s1.num);  //20

        System.out.println(s1.num2);  //30
        System.out.println(Student2.num2);  //30
    }
}

2.什么时候使用static关键字呢?

如果某个成员变量是被所有的对象共享的时候,即值是一样的

3.static关键字注意事项

1)在静态方法中是没有this关键字的

this代表当前调用该方法的对象,static修饰的成员是优先于对象而存在的

static修饰的成员是随着类的加载而加载的,这时候好没有对象产生,也就说明没有this关键字

所以在静态方法中无法使用this关键字

2)静态方法只能访问静态的成员方法

class Student3 {
    private String name;
    private int age;
    private static int a;

//    public static int getAgeAgain(){
//        return this.age;  报错
//    }

    public static void fun1() {
        //尝试访问非静态的成员变量name
        //无法从静态上下文中引用非静态 变量 name
//        System.out.println(name);  报错

        //尝试访问静态的成员变量a
        //静态的成员方法可以访问静态成员变量
        System.out.println(a);

        //尝试访问非静态的成员方法show()
        //无法从静态上下文中引用非静态 方法 show()
        //静态的成员方法不能访问非静态的成员方法
//        show();

        //尝试访问静态的成员方法function()
        //静态的成员方法可以访问静态的成员方法
        function();

    }

    public void fun2() {
        //尝试访问非静态的成员变量name
        //非静态的成员方法可以访问非静态的成员变量name
        System.out.println(name);

        //尝试访问静态的成员变量a
        //非静态的成员方法可以访问静态的成员变量a
        System.out.println(a);

        //尝试访问非静态的成员方法show()
        //非静态的成员方法可以访问静态的成员方法
        show();

        //尝试访问静态的成员方法function()
        //非静态的成员方法可以访问静态的成员方法
        function();
    }

    public static void function() {

    }

    public void show() {
        System.out.println(name + "----" + age);
    }
}

public class StaticDemo2 {
    public static void main(String[] args) {

    }
}

static在内存中的解释

以最上方的案例为例子  

Step1:程序先将class文件(Human.class,HumanDemo.class)加载到方法区中的class文件区       

             Human.class文件区的内容:成员变量,成员方法

             HumanDemo.class文件区的方法:成员变量,成员方法 

Step2:把每个class文件的方法加载到方法区

             Human.class中方法区的内容:构造方法,show()方法,setCountry(String country)(假设这一部分地址值为0x001)

             静态区:

             Human的静态区内容:静态的成员变量country(随着类的加载而加载,此时默认值为null),静态的成员方法(假设这一部分地址值为0x01)

             HumanDemo的静态区内容:静态的成员变量,静态的成员方法main()(假设这一部分地址值为0x02)

Step3:加载完毕,java虚拟机寻找到java的唯一入口main方法,去静态区中找,如果找到了将它加载到栈中去执行

Step4:读到Human h1在栈中开辟空间,读到new Human在堆里面开辟空间(一个创建对象里面包括name,age,静态标记0x01,方法标记0x001)

Step5:一开始创建出来的对象,系统给默认值:name=null,age=0;然后看显示赋值(没有,跳过),继续看构造方法赋值("张杰",42,"中国")(country赋值:按照静态标记0x01找到静态成员变量country,把中国赋给它)(假设在堆中创建对象的地址值为0x0001),有个隐含的this指向0x0001这个区域。初始化值全部都有结束以后,将地址值0x0001赋给栈中的变量h1(变量h1就能通过地址值找到对象在堆内存中的区域)

Step6:读到h1.show();按照h1地址值0x0001找到堆内存中的区域,找到name(张杰),age(42),按照静态标记0x01找到静态区中的country(中国)

Step7:读到Human h2在栈中开辟空间,读到new Human在堆里面开辟空间(一个创建对象里面包括name,age,静态标记0x01,方法标记0x001)

Step8:一开始创建出来的对象,系统给默认值:name=null,age=0;然后看显示赋值(没有,跳过),继续看构造方法赋值("彭于晏",38)(假设在堆中创建对象的地址值为0x0002),有个隐含的this指向0x0002这个区域。初始化值全部都有结束以后,将地址值0x0002赋给栈中的变量h2(变量h2就能通过地址值找到对象在堆内存中的区域)

Step9:读到h2.show();按照h2地址值0x0002找到堆内存中的区域,找到name(彭于晏),age(38),按照静态标记0x01找到静态区中的country(中国)

Step10:读到Human h3在栈中开辟空间,读到new Human在堆里面开辟空间(一个创建对象里面包括name,age,静态标记0x01,方法标记0x001)

Step11:一开始创建出来的对象,系统给默认值:name=null,age=0;然后看显示赋值(没有,跳过),继续看构造方法赋值("蔡徐坤",22)(假设在堆中创建对象的地址值为0x0003),有个隐含的this指向0x0003这个区域。初始化值全部都有结束以后,将地址值0x0003赋给栈中的变量h3(变量h3就能通过地址值找到对象在堆内存中的区域)

Step12:读到h3.show();按照h3地址值0x0003找到堆内存中的区域,找到name(蔡徐坤),age(22),按照静态标记0x01找到静态区中的country(中国)

......

静态变量与成员变量的区别

1.所属不同

静态变量属于类,所以也称为类变量

成员变量属于对象,所以也称为实例对象(对象变量)

2.内存中位置不同

静态变量存储于静态区的而方法区

成员变量存储于堆内存

3.内存中出现时间不同

静态变量随着类的加载而加载,随着类的消失而消失

成员变量随着对象的创建而创建,随着对象的消失而消失

4.调用不同

静态变量可以通过类名调用,也可以通过对象调用

成员变量只能通过对象名调用

main方法的格式讲解

1.public:公共的,访问权限是最大的,因为main是由JVM调用的,所以权限要足够大

2.static:静态的,不需要创建对象,通过类名直接调用,方便JVM访问

3.void:表示无返回值,因为返回值是返回给调用者的,而main方法是由JVM调用的,返回给它没有意义

4.String[] args:参数是一个字符串数组,数组的形参名是args

                      这个怎么么用呢?如何传参呢?值去哪里了呢?

                      JDK1.5之前,没有Scanner键盘录入的时候,程序员就是借助args传参

                      怎么用呢?

                         1.IDEA可以直接传参

                         2.命令传参

                               java 类名 参数


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

+7_big data

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

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

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

打赏作者

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

抵扣说明:

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

余额充值