java中static关键字用法

static关键字

一、用法

1、static关键字表示静态。能与属性,方法,代码块,内部类等一起使用。

2、static修饰属性和方法时,可以直接通过类名.属性或类名.方法来访问。

3、 静态变量:

• 一个类中,静态的变量只分配一块内存空间。多个实例对象共享该内存空间。

• 静态的变量在类加载的时候,被初始化。也就是说,只要类被加载,不管是否使用该静态变量,则都会自动的为其开辟空间,并初始化。

4、静态方法

• 在类加载时,加载到JVM。直接使用类名.方法名调用。

5、 静态代码块

• 是类的组成部分,在类第一次被加载的时候,执行一次。也就说,静态代码块在程序运行时,只能被执行一次。

• 用于初始化静态的属性。

下面来看示例一:

StaticDemo类

package com.jcxy.demo02;

public class StaticDemo
{
    //静态变量
    static int a = 10;
    static String str = "jack";
    //静态方法
    public static void show()
    {
        System.out.println("this is static demo!");
    }
}
Test类

package com.jcxy.demo02;

public class Test
{
    
    /** 
     * 测试static关键字的用法
     * <功能详细描述>
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {
        System.out.println(StaticDemo.a);
        System.out.println(StaticDemo.str);
        StaticDemo.show();
    }   
}
打印输出:

10
jack
this is static demo!

示例二:静态代码块的用法

包含普通成员变量,静态成员变量,静态代码块,动态代码块以及构造函数的类

package com.jcxy.demo02;

public class StaticDemo3
{
    int age = 21;
    
    static String school = "清华";
    
    static
    {
//        school = "北大";
        System.out.println("这是静态代码块");
    }
    
    {
        System.out.println("这是非静态代码块");
    }
    
    public StaticDemo3()
    {
        
        System.out.println("这是对象初始化的构造方法");
    }
}
测试类Test

package com.jcxy.demo02;

public class Test
{
    
    /** 
     * 测试static关键字的用法
     * <功能详细描述>
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {  
        StaticDemo3 sd = new StaticDemo3();
        System.out.println(StaticDemo3.school);
    }   
}
打印结果:

这是静态代码块
这是非静态代码块
这是对象初始化的构造方法
清华


通过打印结果,我们不难看到,

1、当我们new一个对象的时候,是静态变量最先开辟内存(在赋值的情况下),未赋值则跳过。

2、接下才静态代码块。

3、接着调用我们的构造方法,注意,调用构造方法的时候,在执行方法体之前。

4、先对普通成员变量进行初始化(当初赋值的情况下),如果没赋值则跳过。

5、接着才执行非静态方法。

6、最后才执行我们构造方法的方法体。


示例三:静态变量定义在静态代码块后与前的区别

看下面这种的输出结果

package com.jcxy.demo02;

public class StaticDemo1
{
    static
    {
        school = "aaa";
        //System.out.println(school);  编译错误。在定义前无法引用school
    }
    
    public static String school = "清华";
}
Test:

package com.jcxy.demo02;

public class Test
{
    
    /** 
     * 测试static关键字的用法
     * <功能详细描述>
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {
//        System.out.println(StaticDemo.a);
//        System.out.println(StaticDemo.str);
//        StaticDemo.show();
        
        System.out.println(StaticDemo1.school);
    }   
}


打印输出为:清华

为什么呢?

这种情况:

    相当于以下代码:   

    public static String school;
    static{
         school = “aaa”;
         //System.out.println(school);报错
	    }
    school = “清华”;

1- 类加载时,为静态属性分配内存空间,且以默认值填充;

2- 从上向下执行,先为school赋值aaa,再为school赋值清华

但此时要注意的是,声明语句在静态代码块下面,在静态代码块中的如果获得静态属性的值,则会报错。

看第二种情况:

package com.jcxy.demo02;

public class StaticDemo1
{  
    public static String school = "清华";
    static
    {
        school = "aaa";
        System.out.println(school);
    }
}

Test:

package com.jcxy.demo02;

public class Test
{
    
    /** 
     * 测试static关键字的用法
     * <功能详细描述>
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {       
        System.out.println(StaticDemo1.school);
    }   
}

打印:

aaa

aaa

原因分析:

第二种情况:

1- 类加载时,为静态属性分配内存空间,且以默认值填充;

2- 将清华赋值给school

3- 执行静态代码块内容。

因为声明在获得school值之前,所以,可以System.out.println(school);


二、static特点:

1、static可以修饰属性,方法,代码块。此时属性,方法,代码块就成了类变量,静态方法,静态代码块。注意:静态不能修饰局部变量。

2、类变量,静态方法,静态代码块与具体某个对象无关,是属于类级别。如果访问权限允许,通过类名.方法名或类名.属性名访问。

3、静态变量,静态代码块都是在类加载时,执行并初始化。

4、一个类的静态方法或静态代码块,只能访问静态的属性和静态方法,不能直接访问非静态的属性和方法。对于非静态的方法或代码块,可以直接访问静态的或非静态的属性和方法。

5、静态方法或静态代码块中,不能使用this,super关键字。因为this,super是对象,对象在静态之后创建的。

6、静态方法可以被覆盖,但不体现多态;父类如果是静态方法,子类不能覆盖为非静态方法;父类如果是非静态方法,子类不能覆盖为静态方法。

7-构造方法不允许声明为static。因为构造方法是在创建对象时,自动调用;而static属于类级别的。



三、关于静态的用法:

1、静态属性:(类变量)

• 节省内存空间。但生命周期从类加载分配内存开始,到程序结束。

• 实际使用中,当多个对象共享某些数据时,可以将这些设置为静态的变量; 定义常量;

2、 静态方法:

• 不需要创建对象,直接通过类名.方法。静态方法中不能使用非静态的属性和方法。

• 在实际使用中,定义一些和非静态的属性和方法无关的功能时,使用。比如工具类。

3、静态代码块

• 在类加载的时候,只运行一次。

• 实际的使用中,比较少。比如,JDBC时,数据库驱动的加载,可以放在静态代码块中,仅加载一起,后续就可以直接使用。



总的来说,对于static关键字的理解就是要能够理解static修饰的属性或者方法的加载的顺序。那要理解加载的顺序,我们可以通过debug调试来追踪发现。如果想要更深入了解的话,可以通过内存分析来看更加的直观。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值