欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java基础_面向对象_static关键字

程序员文章站 2024-03-17 16:17:58
...

    一直感觉对静态的理解不到位,知道修饰类的属性和方法、修饰代码块(不能修饰普通类但是可以修饰内部类)。在合适的环境下,提高程序的运行性能,优化程序的结构;反之,不合理的运用因为难以被GC掉,构成内存负担造成内存溢出,在android开发中尤为明显,有些闪退就是因为out of memory。

   再去重新理解static的时候我想从最简单的开始,修饰类的属性。

目录


(1) 修饰类的属性

   在类中,static修饰的成员变量称为静态成员变量,它为该类的公有变量,只有在第一次使用时被初始化,对于该类所有对象来说,static成员变量只有一份。

    静态成员变量是属于整个类的,不属于具体的某个对象。那么对这个静态的值怎么访问呢?首先,任何一个对象都可以访问这个静态的值,访问的时候都是访问的同一块内存 。其次,即便是没有对象,你也可以类名.访问这个值。

    举个简单的列子,猜一下输出的结果,然后内存上分析咋回事。

public class Test {
    public static void main(String[] args) {
        Cat.sid = 100;
        Cat cat1 = new Cat();
        Cat cat2 = new Cat();

        cat1.info();
        cat2.info();
    }
}
public class Cat {
    static int sid;
    int id;

    public Cat() {
        id = sid++;
    }

    public void info() {
        System.out.println("static cat:" + "sid=" + sid + "  id=" + id);
    }
}

显然定义了static int sid,结果:挺有意思。

static cat:sid=102  id=100
static cat:sid=102  id=101

加载过程,JVM内存分四种:

  1. 栈区(stack segment)- 由编译器自动分配释放,存放函数的参数值,局部变量的值等,具体方法执行结束之后,系统自动释放JVM内存资源。
  2. 堆区(heapsegment)- 存放new出来的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收掉。
  3. 方法区(也叫:数据区,共享区,共享数据区) - 存放全局变量,静态变量和字符串常量,和方法。
  4. 代码区(codesegment) - 存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域。

因此首先Cat.sid = 100;数据区中专门分配一小块位置存放。
其次Cat cat1 = new Cat();位置栈空间中分配一块名为cat1,值是指向另一大块内存的地址;堆空间中分配一大块内存用于new出来的对象,其中对象的属性id被赋值为100;id = sid++; sid++后为101;同理cat2时,此时sid=101,cat2的id值被赋予101,然后sid为102;

java基础_面向对象_static关键字

以上也就说明了静态成员变量是属于整个类的,不属于具体的某个对象。

那么我们试着把static int sid; 改为非静态int sid; 最后输出:

non static cat:sid=1  id=0
non static cat:sid=1  id=0

(2) 修饰类的方法

   用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可以访问非static的成员。
   动态方法是针对于某一个对象进行调用的。静态的方法呢?它不针对某一个对象,和静态成员变量一样是属于整个类的,没有对象照样可以调用,就像Cat.静态方法。也正因为如此静态方法中不能访问非static的成员和非静态的方法,比如在main方法中id=9会报错的。
   在工具类中常会有修饰方法,方便调用,免去new对象这个繁琐的过程。比如:TextUtils.isEmpty(string) 源码

     public static boolean isEmpty(@Nullable CharSequence str) {
        if (str == null || str.length() == 0)
            return true;
        else
            return false;
    }

(3) 修饰代码块

   静态代码块一般和类的加载相关,可以将多个类成员放在一起初始化。


   常见提示错误: 无法从静态上下文中引用非静态 变量 this

   this 是指向当前对象的引用,需要对象实例化以后才能赋值。而静态成员都是类所属的,不需要对实例化就可以使用,所以在静态上下文中引用this时可能其还未赋值,所以应不能这样使用。

   在静态方法内只能引用静态变量

关于static简单的入门级总结就是以上这些,如有疑问或者质疑烦劳留言或私信。

“爱情来得快 去得也快 只有猪肉卷是永恒的” –加菲猫。
同理“爱情来得快 去得也快 只有java是永恒的”。