公司新来的小姐姐不懂java中的static关键字,这样给她描述不香吗?

前言

static关键字是摆在刚入行编程语言的小白们面前的一道难题,为何要用static?使用它有什么好处?修饰方法和修饰变量有什么区别?本文将就java中static关键字的使用方法及注意事项进行深刻探讨,一是为了方便本身之后查阅,二也为了与你们交流分享学习的经验。java

1、什么是static关键字

static表示静态,经常使用来修饰成员变量、成员方法、代码块和内部类,存放在方法区,做用在于建立独立于对象存在的域变量或方法,当类被加载时,被static修饰的变量或方法就能够经过类名进行访问,当建立多个对象时,被static修饰的变量/方法不会所以创建多个数据。面试

咱们经过下面一段代码来解释一下它的功能:编程

public class Demo1 {
    public static void main(String[] args) {
        Test.p="静态变量赋值了";
        Test.say();
        new Test();
    }
}
class Test{
    Test(){
        System.out.println("构造方法执行了");
    }
    static String p ;
    static{
        System.out.println("静态代码块执行了");
    }
    public static void say(){
        System.out.println("静态方法执行了");
        System.out.println(p);
    }
    public void say2(){
        System.out.println("方法执行了");
        System.out.println(p);
    }
}

代码中咱们分别使用关键字static定义了静态变量、静态代码块和静态方法,执行结果以下编程语言

咱们发现,最早执行的语句是static修饰的代码块,在咱们经过类名直接调用方法say以前就执行了,随后是咱们经过类名访问的静态方法say,最后才是构造方法。到这里小白可能会问,为何咱们尚未建立对象就能够访问类中的内容呢?这就涉及到了关键字static的使用方法。性能

2、static关键字的使用方法

1.修饰变量和方法**

被static修饰的变量和方法咱们统称为静态变量和静态方法,属于类的静态资源,是类实例之间共享的,简单地说,即不随着建立对象的改变而发生改变。以普通变量和方法为例:咱们写一段简单的代码学习

public class Demo1 {
    public static void main(String[] args) {
        Test t1 = new Test();
        Test t2 = new Test();
        t1.p = "变量赋值了";
        t1.x =1;
        t2.x =2;
        t1.say();
    }
}
class Test{
    String p;
    static int x;

    void say(){
        System.out.println("方法执行了");
        System.out.println(p);
        System.out.println(x);
    }
}

这段代码很简单,即咱们经过建立的对象t来访问Test类中的内容,与上一段代码不一样的是咱们不能经过类名的方式来直接调用这些变量方法,如Test.p和Test.say,而是要经过建立的新对象t。可是咱们却能够用对象t来访问静态变量x,可是变量x的内容属于类,对象t1,t2是共享一个变量x的,经过两个对象赋值后,结果取最后赋的值,因此输出的结果以下。
优化

2.静态代码块

静态静态块也是static的重要应用之一。一般使用于类的初始化,和静态变量、静态方法同样,静态块里面的代码只执行一次,且只在初始化类的时候执行。
为了更清楚地描述静态代码块的功能,咱们编写以下代码。this

public class Demo1 {
    public static void main(String[] args) {
        new Test2();
        new Test1();
    }
}
class Test2 extends Test1{
    static{
        System.out.println("静态代码块1执行了");
    }

    static{
        System.out.println("静态代码块2执行了");
    }
}

class Test1{
    static {
        System.out.println("静态代码块3执行了");
    }
}

不难看出,静态代码块随着对象的建立,或者说类的实例化而进行,且只进行一次,咱们建立了两个对象,可是每一个语句只打印了一次。咱们根据他们打印的顺序能够推断出静态代码块的执行规则。
1.按照父类到子类的顺序执行。
2.在同一个类中按照代码的顺序执行
3.每一个静态代码块只执行一次
静态代码块能够优化程序性能,正是由于它的特性:只会在类被初次加载的时候执行一次。
spa

3.静态内部类

static正常状况下是不能用来修饰类的,它只能修饰内部类,也就是咱们说的静态内部类,它的应用场景相对于以上两个功能少得多,一般咱们使用内部类时会保存一个引用,引用是指向建立它的外围内,可是静态内部类却没有。没有这个引用就意味着:
一、它的建立是不须要依赖外围类的建立。
二、它不能使用任何外围类的非static成员变量和方法。
咱们经过代码示例来简单地介绍一下静态内部类使用方法code

package com.java.demo1;

public class Demo1 {
    public static void main(String[] args) {
        Test.Test2 t = new Test.Test2();
        t.say();
    }
}
class Test {
     static class Test2 {
         void say(){
             System.out.println("静态内部类");
         }

    }
}

3、为何要使用static

好了,说到这里,可能一些初学者会问,为何要使用静态呢?首先咱们总结一下被静态static修饰的变量/方法/方法块/类的特色

静态修饰的特色
1.被static修饰的变量/方法是独立与类所建立的对象而存在的,简而言之,当咱们建立多个对象实例时,static修饰的变量/方法是被它们所共享的,即不随着不一样对象的建立而发生改变。
2.static在类加载时就建立好了内存空间,可是它的内容是能够改变的,咱们能够经过不一样的对象给它赋值,可是它的值取决于你最终给它的赋值。
3.即使不建立对象,static修饰的变量或方法也是能够存在的,当一个类加载完毕后,类中static修饰的变量和方法就能够进行访问。
静态修饰的优势

1.方便在咱们没有建立对象时,调用类中的方法/变量
2.static能够用来修饰类的成员方法、成员变量或编写static代码块,可以有效地优化程序性能
咱们能够经过下面一段代码来直观地感觉一下

package com.java.demo1;

public class Demo1 {
    public static void main(String[] args) {
        Test t1 = new Test();
        Test t2 = new Test();
        Test t3 = new Test();
        t1.name = "张三";
        t2.name = "李四";
        t3.name = "王麻子";
        t1.age = 18;
        t2.age = 18;
        t3.age = 19;
        Test.school = "清华大学";
        t1.say();
        t2.say();
        t3.say();
    }
}
class Test {
     String name;
     int age;
     static String school;
     void say(){
         System.out.println("我是"+name+",今年"+age+"岁,就读于"+school);
     }
}

运行结果以下

对于三个对象,他们的school属性是彻底相同的,所以为了避免占用过多内存,咱们用static把变量school修饰成静态变量,若是咱们发现变量school的内容写错了,也能够经过一次修改就达成修改全部对象的目的。

4、注意事项

介绍完了static的优势,接下来讲一些使用static关键字时常常出现的错误和须要你们注意的一些细节。

1.static不会改变类中成员的访问权限

不少初学者容易把java中的static和C/C++中的static搞混了,在C/C++中,static可以改变成员的访问权限,而这在java中时不行的,在java中只能经过四个权限修饰符来改变成员的访问权限

如图所示,咱们直接给private封装的变量school赋值时,会提示错误。

2.静态方法不能引用非静态资源

这一点是初学者常常犯的错误,当咱们定义了一个非静态的变量/方法后,若是咱们经过静态的变量或方法来访问非静态的资源时程序是会报错的。这其实不难理解,咱们以前说过,静态修饰的变量/方法在类初始化时加载,它们的建立顺序是在非静态资源以前的,咱们用已经建立的资源去访问没有被建立的资源,这显然是不合理的。但反过来,非静态资源/静态资源则是能够访问静态资源的。咱们经过代码来直观地感觉一下。

3.能够经过this来访问静态的资源

虽然咱们以前提到过,静态的资源自己是独立于实例化的对象而存在的,可是咱们却能够经过对象来访问静态的资源,全部的静态方法和静态变量均可以经过对象访问(只要访问权限足够)。咱们再经过一个案例来感觉:

public class Demo1 {
    public static void main(String[] args) {
        Test t = new Test();
        t.say();
    }
}
class Test {
      static int num = 1;
      void say(){
         int num = 2;
          System.out.println(this.num);
     }
}

结果输出为1,代码中的this.num并无指向方法say中定义的num,这里的this仍是指向了Test类,显然咱们是能够经过对象自己来访问静态资源的。

最后

你们看完有什么不懂的能够在下方留言讨论,也能够关注我私信问我,我看到后都会回答的。也欢迎你们关注个人公众号:前程有光,立刻金九银十跳槽面试季,整理了1000多道将近500多页pdf文档的Java面试题资料放在里面,助你圆梦BAT!文章都会在里面更新,整理的资料也会放在里面。谢谢你的观看,以为文章对你有帮助的话记得关注我点个赞支持一下!