java面向对象之static(2)

static

介绍

我们希望无论是否产生多少对象,某些特定的数据在内存空间里只有一份

  • static可以称作是静态或者全局
  • 可以修饰的范围:成员变量和方法及代码块
  • 独立于任何实例化对象,不依赖于对象可以直接用类进行访问
  • 直接上案列:

(1)成员变量static

	public class Person {
    String name;
    static int age;

	public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }
}

那么这里结果显而易见:p2的age赋值后影响了p1的age,对它有了干扰,给age属性加了static关键字之后,Person对象就不再拥有age属性了,age属性会统一交给Person类去管理,即多个Person对象只会对应一个age属性,一个对象如果对age属性做了改变,在这个类中的其他的对象都会受到影响,而且在jvm中它是和类(person)放在一起的,存放在静态存储区,既不在stack中也不在heap中,并且是在类加载前完成了赋值初始化操作,其实在实际中通常没这么用

所以由此我们能注意到他们的区别静态变量和非静态变量的区别:

  • 静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化

  • 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响

那么我们实在是希望属性共享怎么办:

public class Person {
    private static int count = 0;
    int id;
    String name;
    int age;
    
    public Person() {
        id = ++count;
    }
    
    public String toString() {
        return "Id:" + id + ", Name:" + name + ", Age:" + age;
    }
    
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }
    /**Output
     * Id:1, Name:zhangsan, Age:10
     * Id:2, Name:lisi, Age:12
     */
}

这里我们设置了id来区别main中的对象实现了属性的这样一个共享,除此之外还记录了对象的数量


(2)成员方法的static
首先我们知道,相比于修饰成员属性,修饰成员方法对于数据的存储上面并没有多大的变化,只是有一个小优势防止多次new造成的内存开销,和书写繁琐

public class PrintHelper {

    public static void print(Object o){
        System.out.println(o);
    }
}

但是他也有局限,使得它经常在帮助类中使用,一个静态修饰的static中不能使用非static修饰的成员变量和方法,这个其实很好理解,因为static修饰的方法是属于类的,如果去直接使用对象的成员变量,它会不知所措(不知该使用哪一个对象的属性)

总结

最后说明一下他们在jvm中的加载顺序:,当我们new一个对象时,static修饰的成员变量首先被初始化,随后是普通成员,最后调用Person类的构造方法完成初始化。也就是说,在创建对象时,static修饰的成员会首先被初始化(意思是创建对象之前完成),而且我们还可以看到,如果有多个static修饰的成员,那么会按照他们的先后位置进行初始化

static是java中非常重要的一个关键字,而且它的用法也很丰富,主要有四种用法:

  1. 用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;
  2. 用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;
  3. 静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键;
  4. 静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。
  5. 由于类只会加载一次,所以static成员也只加载一次,生命周期相同
  6. 存在方法区的静态域中
  7. 静态方法中只能有静态的属性和方法,非静态方法中既可以有静态也可以有非静态
  8. 静态方法中不能有this和super
发布了38 篇原创文章 · 获赞 1 · 访问量 2266

猜你喜欢

转载自blog.csdn.net/CRD8843/article/details/103702224