深入理解static的作用以及被static修饰的变量、方法、块

简介: static关键字有以下三种使用方法:1.被static修饰的变量属于静态变量,类变量,可以通过类名,变量名直接引用,不需要进行new一个新类。2.被static修饰的方法属于静态方法,类方法,可以通过类名,方法名直接引用,而不需要new出来一个对象3.静态块,用于初始化一个类的时候进行一些操作,静态变量、静态方法和静态代码块都只执行一次,而且只在初始化的时候执行。
static的作用

static关键字有以下三种使用方法:

1.被static修饰的变量属于静态变量,类变量,可以通过类名,变量名直接引用,不需要进行new一个新类。


2.被static修饰的方法属于静态方法,类方法,可以通过类名,方法名直接引用,而不需要new出来一个对象


3.静态块,用于初始化一个类的时候进行一些操作,静态变量、静态方法和静态代码块都只执行一次,而且只在初始化的时候执行。

首先静态变量:

静态变量被所有变量所共享,在内存中只存在一种副本,只在(当且仅当)类初次加载时被初始化,生命周期边长,只有程序结束才能够被销毁。而非静态变量是单个对象所拥有的,存在多个副本,各个对象之间副本互不影响。

其次静态方法:

静态方法是所有类都能够调用和共同存在的方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为this表示是当前对象,因为它不依附于任何对象,既然都没有对象,就谈不上this了。 并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。 最大的作用就是可以”类名.方法名”调用该方法。但是在实际开发中也少用到该方式,因为一是static修饰后的方法资源共享,在多线程场景不安全。二是静态资源常驻内存,很难被回收,


注意:

被static修饰的变量和被static修饰的方法统一属于类的静态资源,是类实例之间共享的,换言之,一处变、处处变。

其次静态方法:

static修饰静态块后,将要修饰的成员同一放在一个static中。该静态化会在第一次使用类时,最先初始化static修饰的静态块。并且在程序运行过程中,只需要初始化一次,不会进行多次初始化。以下代码是静态代码块以流的模式获取test.properties文件内容。

static {
  Properties prop = new Properties();
  InputStream in = Object.class.getResourceAsStream("/test.properties");
  try {
    prop.load(in);
    param1 = prop.getProperty("initYears1").trim();
    param2 = prop.getProperty("initYears2").trim();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

那么我们思考,为什么 JDK把不同的静态资源放在了不同的类中而不把所有静态资源放在一个类里面,很多人可能想当然认为当然要这么做,但是是否想过为什么要这么做呢?个人认为主要有三个好处:


1、不同的类有自己的静态资源,这可以实现静态资源分类。比如和数学相关的静态资源放在java.lang.Math中,和日历相关的静态资源放在java.util.Calendar中,这样就很清晰了


2、避免重名。不同的类之间有重名的静态变量名、静态方法名也是很正常的,如果所有的都放在一起不可避免的一个问题就是名字重复,这时候怎么办?分类放置就好了。


3、避免静态资源类无限膨胀,这很好理解。


OK,再微微深入一下,也是有些人容易混淆的一个问题:静态方法能不能引用非静态资源?静态方法里面能不能引用静态资源?非静态方法里面能不能引用静态资源?比如就以这段代码为例,是否有错?

1 public class A
2 {
3     private int i = 1;
4     
5     public static void main(String[] args)
6     {
7         i = 1;
8     }
9 }

当然有错,在第7行的地方。不妨这么思考这个问题:


静态资源属于类,但是是独立于类存在的。从JVM的类加载机制的角度讲,静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的。类的初始化早于类的new,比如Class.forName(“xxx”)方法,就是初始化了一个类,但是并没有new它,只是加载这个类的静态资源罢了。所以对于静态资源来说,它是不可能知道一个类中有哪些非静态资源的;但是对于非静态资源来说就不一样了,由于它是new出来之后产生的,因此属于类的这些东西它都能认识。所以上面的几个问题答案就很明确了:


1、静态方法能不能引用非静态资源?不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。


2、静态方法里面能不能引用静态资源?可以,因为都是类初始化的时候加载的,大家相互都认识。


3、非静态方法里面能不能引用静态资源?可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。

相关文章
|
7月前
final修饰的变量有三种
final修饰的变量有三种
87 0
|
7月前
|
C语言
学习static定义静态变量
学习static定义静态变量。
68 4
|
2月前
学习 static 定义静态变量的用法
学习 static 定义静态变量的用法。
52 13
|
7月前
|
存储 C语言 C++
C/C++静态static属性/用法
C/C++静态static属性/用法
53 0
|
7月前
|
C语言
c语言中的static静态(1)static修饰局部变量
c语言中的static静态(1)static修饰局部变量
68 1
|
7月前
|
存储 设计模式 算法
[C++] static静态成员变量/函数的用法
[C++] static静态成员变量/函数的用法
109 1
|
Java
final 类,常量,方法的解释
final 类,常量,方法的解释
98 1
|
Java 编译器
serialVersionUID 不是被 static 变量修饰了吗?为什么还会被“序列化”?
serialVersionUID 不是被 static 变量修饰了吗?为什么还会被“序列化”?
|
存储 C语言
static的作用
static的作用
163 0