java基础---static关键字

一、static介绍

static:表示“全局”或者“静态”的意思,但是Java语言中没有全局变量的概念。

修饰:成员变量和成员方法,也可以形成静态static代码块。Java中static是不允许用来修饰局部变量。

作用:方便在没有创建对象的情况下来进行调用(方法/变量)。只要类被加载了,也就是在它的任何对象创建之前,就可以通过类名去进行访问。

        被static修饰的成员变量成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。


二、什么时候使用static

1.静态变量:在我们创建一个类的实例时(对象),通常使用new方法,这样这个类的数据空间才会被创建,其方法才能被调用。但是,有时候我们希望一个类虽然可以被创建n个对象(显然这n个对象的数据空间是不相同的),但这n个对象的某些数据是相同的,即不管这个类有多少的实例,这些数据对这些实例而言之有一份内存拷贝。这是静态变量的情形。


2.静态方法:另一种情形是,你希望某个方法不与包含它的类的任何对象关联在一起。也就是说,即使没有创建对象,也能够调用这个方法。static 方法的一个重要用法就是在不创建任何对象的前提下,就可以调用它。这是静态方法的情形。


3.内部类:还有一种特殊的用法出现在内部类中,通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。这是静态类的情形。


静态变量:

按照是否静态对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量

两者的区别是:
1.对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态变量分配一次内存,它当且仅当在类初次加载时会被初始化,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。static成员变量的初始化顺序按照定义的顺序进行初始化。
2.对于实例变量,每创建一个实例,就会为实例变量分配一次内存,在创建对象的时候被初始化,实例变量可以在内存中有多个拷贝,互不影响(灵活)。

public class TStatic {
    static int i;
 
    public TStatic() {
       i = 4;
    }
 
    public TStatic(int j) {
       i = j;
    }
 
    public static void main(String args[]) {
       System.out.println(TStatic.i);
       TStatic t = new TStatic(5); // 声明对象引用,并实例化。此时i=5
       System.out.println(t.i);
       TStatic tt = new TStatic(); // 声明对象引用,并实例化。此时i=4
       System.out.println(t.i);
       System.out.println(tt.i);
       System.out.println(t.i);
    }
}

结果:
0
5
4
4
4
        static变量在类被载入时创建,只要类存在,static变量就存在。它们在定义时必须进行初始化。上例中没有初始化i,所以会得到默认的初始值0。static的变量的初始化仅能一次,static变量只是接受了最后一次的初始化。实际这还是多个实例共享一个静态的变量的问题。



静态方法:

1.static方法一般称作静态方法,静态方法可以直接通过类名调用,任何的实例也都可以调用。

2.由于静态方法不依赖于任何对象就可以进行访问,因此静态方法中不能用this和super关键字因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的

3.因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。

4.即使没有显示地声明为static,类的构造器实际上也是静态方法

为什么静态方法中不能访问类的非静态成员变量和非静态成员方法而非静态成员方法中是可以访问静态成员方法/变量的?
理由很简单,对于静态的东西,JVM在加载类时,就在内存中开辟了这些静态的空间(所以可以直接通过类名引用),而此时非静态的方法和成员变量所在的类还没有实例化。所以如果要使用非静态的方法和成员变量,可以直接在静态方法中实例化该方法或成员变量所在的类。public static void main就是这么干的。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。


static代码块
        static代码块也叫静态代码块,作用是优化程序性能,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次

为什么说static块可以用来优化程序性能?是因为它的特性:只会在类加载的时候执行一次。下面看个例子:

class Person{
    private Date birthDate;
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
    boolean isBornBoomer() {
        Date startDate = Date.valueOf("1946");
        Date endDate = Date.valueOf("1964");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}
isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:
class Person{
    private Date birthDate;
    private static Date startDate,endDate;
    static{
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
    }
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
    boolean isBornBoomer() {
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}
因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。



参考来源:

Java关键字介绍之static

Java中的static关键字解析

Java关键字final、static使用总结





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值