浅谈static关键字

static是一个修饰符

通常用在以下四个场景:
(1)修饰成员变量
(2)修饰成员方法
(3)静态代码块
(4)静态导包
现在就以上四个方面讨论static关键字

一、static修饰成员变量
static修饰的成员变量---->静态变量
(1)静态变量属于类,被所有对象共享,不属于任何一个对象(和对象解绑)。
(2)静态变量存储在共享数据区的方法区中。
(3)静态变量在内存中只有一个副本,当且仅当在类初次加载时会被初始化。
(4)非静态变量是对象所拥有的,存在多个副本,在创建对象时被初始化。

二、static修饰成员方法
static修饰的成员方法---->静态方法
(1)静态方法不需要依赖对象就可以访问,所以静态方法没有this。
(2)静态方法不能访问类的非静态成员变量和非静态成员方法,因为非静态的成员变量和方法必须依赖具体的对象才能被调用。
(3)非静态成员方法中是可以访问静态成员的变量和方法的。

我们来看下面的代码:

public class StaticTest {

    private static int a = 3;//静态变量
    private int b = 6;//非静态变量

    //非静态方法
    public void test1(){
        int a = 30;//局部变量a不跟this关联
        System.out.println (this.a);//输出3,全局变量a被所有对象共享
    }

    //非静态方法
    public void test2(){
        System.out.println (a);//可访问静态变量
        System.out.println (b);//可访问非静态方法
        test3 ();//可访问静态方法
    }

    //静态方法
    public static void test3(){
        System.out.println (a);
        //System.out.println (b);//编译错误,静态方法不可以访问非静态方法
        //test2();//无法访问非静态方法
    }

    public static void main(String[] args) {
        StaticTest.test3 ();//直接通过类名访问静态方法

        //创建一个对象
        StaticTest s = new StaticTest ();
        s.test1 ();//对象调用非静态方法
    }

}

其中几点要注意:
(1)在非静态方法中定义一个和全局变量同名的局部变量,但this所指向的当前对象依然是全局变量a。
在这里插入图片描述
(2)静态方法无法访问非静态变量和非静态方法。
在这里插入图片描述
(3)静态方法可以直接通过 “类名.方法名” 来调用。非静态方法必须通过对象去调用。
在这里插入图片描述
三、静态代码块
类在加载时,先按照static块的顺序执行每个代码块,并且只执行一次。

class Person{
    
    static{
        System.out.println("person static");
    }
    
    public Person(String str) {
        System.out.println("person "+str); 
    }
    
}

class MyClass extends Test {

    Person person = new Person ("MyClass");

    static {
        System.out.println ("myclass static");
    }

    public MyClass() {
        System.out.println ("myclass constructor");
    }
}

public class Test {

        Person person = new Person("Test");

        static{
            System.out.println("test static");//1
        }


        public Test() {
            System.out.println("test constructor");
        }

        public static void main(String[] args) {
            new MyClass();
        }
        
}

输出:
在这里插入图片描述
(1)一个程序运行,找到程序入口main方法,main方法在Test类,执行main方法首先要先加载Test类,Test类中有静态代码块,在类加载时执行,故输出test static。
(2)接着执行main函数中的对象的创建,即new MyClass();MyClass类还未被加载,故加载,加载过程中发现 MyClass类继承自Test类,要先加载其父类,但Test类在步骤(1)中已经加载,所以只加载MyClass类即可。先执行其中的静态代码块,所以输出myclass static。
(3)加载结束后,根据代码顺序构造新的对象,在生成对象之前,必须先初始化父类的成员变量,所以会先执行Test类中的对象的构造,即Person person = new Person(“Test”);但Person类还没有加载,所以加载Person类,执行其中的静态代码块,输出person static。
(4)接着执行Person类中的构造方法,输出person Test。
(5)接着执行父类Test中的构造方法,输出test constructor。
(6)随后执行MyClass类自身的初始化,输出person MyClass。
(7)指向MyClass类的构造方法,输出myclass constructor。

四、静态导包

import static 类名;

将"类名"类中的所有方法直接导入,无需"类名.方法名"去调用类方法,直接使用方法名即可调用类方法。

注意:

1.Java中static是不允许用来修饰局部变量的。(C\C++可以)
2.static关键字不会改变该变量和方法的访问权限。
3.静态成员虽然独立于对象,但是不代表不可以通过对象去访问。所有的静态方法和静态变量都可以通过对象去访问。(在访问权限允许的前提下)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值