美文网首页
Java中的static

Java中的static

作者: 康小曹 | 来源:发表于2021-02-23 15:58 被阅读0次

一、概念

在《Java编程思想》P86页有这样一段话:

“static方法就是没有this的方法。在 static 方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用 static 方法。这实际上正是 static 方法的主要用途。”

C/C++/OC 中存在全局变量、全局方法的概念,而 Java 中,除了一些特殊的代码,比如 import、enum的声明等,所有的代码都必须写在类中。因此,在 Java 中就不存在全局变量、全局方法这种概念。

而全局变量就是存储在全局区的变量,直到程序结束时,生命周期才被销毁,Java 中也肯定存在这种需求,所以肯定需要一个替代方案,而 static 就是一种选择。

静态的概念:

  1. 存储在 data 区(全局区);
  2. 只有一份内存,修改之后影响全局;
  3. Java 中以类为维度,所以会存在一个归属问题,在哪个类中定义,那么这个静态变量/方法就只能通过这个类或者这个类的实例来访问;

二、场景

1. static 修饰局部变量

Java 中的 static 不能修饰局部变量!!!

其原因可能涉及到:

  1. Java 语言的设计理念问题;
  2. Java 编译器的实现问题,实现一个非必要的功能徒增工作量;
  3. 是否有必要或者已有替代方案(比如类的静态成员变量就可以实现相同的需求);

2. static 修饰成员变量

本质上而言,static 修饰成员变量就是和 C 中的 static 一样,将成员变量转移到了 data 区,不改变作用域,改变了生命周期。但是 Java 中代码都写在类中,没有全局变量的概念,所以需要使用类作为承载。

而 OC 中则不一样。 Java 的设计更加面向对象,就连 main 函数都是对象驱动的,而 OC 中则存在更多面向过程的影子。main 函数的地址是通过 dyld 加载 mach-O 文件时找到并将命令行指向那个位置的。

因此,OC 中不能使用 static 修饰类成员变量:

OC是不能使用static修饰成员属性

究其原因有几点:

  1. 没必要

OC 中没有以类的维度来划分代码。需要一个全局静态变量直接写在全局代码区(文件的非类、函数区域)即可,需要一个局部静态变量,直接写在栈代码区(函数内部)即可。

  1. 歧义
    如果真这么做了,那么静态变量就和类之间建立了关联,还需要存储和类相关的信息。本质上而言, static 只是改变变量的生命周期,如果和类关联起来,按照 OC 中 ARC 谁持有谁管理的观念,难道类在释放之后,或者在类对象加载时,还要去管理这个静态变量?无意义还引起误会。

3. static 修饰方法

static 修饰方法可以用一句话概括:

  • static方法就是没有this的方法。

其有几个特点:

  1. 不需要对象实例就可以直接调用,作用有点类似于 OC 中的类方法;
  2. 因为没有 this,所以静态方法中不能访问类的非静态成员变量和非静态成员方法;
  3. 静态变量是属于类的,但是也可以通过对象访问(本质还是因为静态意味着data,权限足够而且有办法找到函数地址就可以访问);

使用示例:

public class Main {
    public static void main(String[] args) {
        // 不需要对象就可以直接访问
        XKPerson.StaticFunc();
        // 虽然静态方法属于类,但是也可以通过对象访问
        new XKPerson().StaticFunc();
    }
}

class XKPerson {
    static final String COUNTRY = "CHINA";
    int age;

    static public void StaticFunc(){
        System.out.println("StaticFunc");

        // static方法中没有this,不能访问非静态成员变量
        System.out.println(age); //compile error

        // 可以访问静态成员变量(本质上就是data区的数据)
        System.out.println(COUNTRY);
    }
}

特殊情况:

  • 对象为 null 时调用静态方法不会出现空指针异常;

正常情况下,如果一个对象为 null,调用该对象的任何示例方法都将引起空指针异常,但是如果是调用静态方法则可以正常调用:

对象:

class XKPerson {

    static final String COUNTRY = "CHINA";

    static public void StaticFunc(){
        System.out.println("123");
    }

    public void InstanceFunc(){
        System.out.println("456");
    }
}

main函数:

XKPerson p1 = null;
p1.StaticFunc();
p1.InstanceFunc();

结果:

123
Exception in thread "main" java.lang.NullPointerException
    at com.company.Main.main(Main.java:15)

四、static 修饰类

修饰个屁的类哦,你喝多了吧...

Java 里面 static 一般用来修饰成员变量或函数,但有一种特殊用法是用 static 修饰内部类。

普通类是不允许声明为静态的,只有内部类才可以。被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类,最常见的使用是解决 AsyncTask 内存泄漏问题:

public class MainActivity extends AppCompatActivity {

    MainAsyncTask asyncTask;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        asyncTask = new MainAsyncTask();
        // 入参会被传递到doInBackground方法中,可以传递多个值
        asyncTask.execute(100);
    }

    public static class MainAsyncTask extends AsyncTask<Integer,Integer,String> {
        // asyncTask 逻辑
    }
}

此时静态内部类 MainAsyncTask 已经不引用 MainActivity 了,所以当 MainActivity 被 destory 打包 MainAsyncTask 还在执行任务时,不会影响 MainActivity 的销毁;

于此同时

被 static 修饰的内部类:

  1. 已经不是严格意义上的内部类了;
  2. 不能再使用外部类中的实例方法和属性了(因为相当于和外部类平行,除非传一个外部类的实例对象过来才可以使用);
  3. 内部类不再引用外部类(非静态内部类默认引用外部类);
  4. 因此,使用静态内部类解决 AsyncTask 的内存泄漏问题时,局限性很大,只适用于 AsyncTask 和 外部类 Activity 没有交互时;

参考:https://blog.csdn.net/vcliy/article/details/85235363

五、总结

static 的适用范围,在 C/C++/OC 中:

  1. 修饰局部变量;
  2. 不能修饰成员变量;
  3. 修饰全局变量;
  4. 修饰方法;

在 Java 中:

  1. 不能修饰局部变量;
  2. 修饰成员变量;
  3. Java 中无全局变量一说;
  4. 修饰方法;

相关文章

  • java - 关键字 static

    一 static 代表着什么 在 java 中,static 表示静态的意思,并不是全局的意思,在 java 中不...

  • java面试问题总结与分享,很乱

    java中static关键字的作用 在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员...

  • 【JAVA】Java中的static

    0x01 static的作用 static代表它修饰的那个东西是属于整个类的。 0x02 static的特点 st...

  • Kotlin学习2

    1.Kotlin中static在kotlin中 没有static关键字,但是有类似java中static的用法例如...

  • 1.3 static 关键字

    static 关键字 《Java编程思想》 中:static方法就是没有this的方法 static 修饰的方法或...

  • Java中的static

    1、 static在java中到底代表什么,为何要用它? static――静态――“指定位置“ 首先,我们来看看j...

  • Java 中的 static

    Java 中的 static 使用之静态变量 大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己...

  • Java中的static

    一、概念 在《Java编程思想》P86页有这样一段话: “static方法就是没有this的方法。在 static...

  • Java中的static和final

    java中的static和final 此篇文章是记录我在学习Java中static和final关键字的笔记。 st...

  • 复习Java基础资料

    Java中面向字符的输入流 Java中的static关键字解析 Java中的main()方法详解 Java中普通代...

网友评论

      本文标题:Java中的static

      本文链接:https://www.haomeiwen.com/subject/ewlrfltx.html