Java:static关键字

static是一个关键字,这个关键字主要可以用来定义属性和方法,下面将针对于此关键字的使用进行分析。

static定义属性

在一个类之中,所有的属性一旦定义了实际上内容都交由各自的堆内存空间所保存。

范例:定义一个程序类

class PersonStatic {
    private String name;
    private int age;
    private String country="中华民国";
    public PersonStatic(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getInfo(){
        return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + this.country;
    }
}
public class staticJava {
    public static void main(String[] args) {
        PersonStatic perA = new PersonStatic("张三",10);
        PersonStatic perB = new PersonStatic("李四",11);
        PersonStatic perC = new PersonStatic("王五",12);
        System.out.println(perA.getInfo());
        System.out.println(perB.getInfo());
        System.out.println(perC.getInfo());
    }
}

为了更好的观察出程序的问题,下面对此操作做一个内存分析。

在正常开发过程之中每一个对象要保存有各自的属性,所以此时的程序没有任何的问题,但是突然有一天,国家解放了,变为了中华人民共和国。并且你已经产生了5000万个对象,那么此时面对你的将是场噩梦。因为每一个对象都拥有各自的country属性,所以此时会发现从整体的设计上出现了问题:重复保存,修改不便。

此时最好的解决方法就是将country修改为公共属性,而这种情况下就必须使用static进行标注.

范例:修改PersonStatic类定义,使用static定义公共属性。

class PersonStatic {
    private String name;
    private int age;
    static String country="中华民国";
    public PersonStatic(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getInfo(){
        return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + this.country;
    }
}
public class staticJava {
    public static void main(String[] args) {
        PersonStatic perA = new PersonStatic("张三",10);
        PersonStatic perB = new PersonStatic("李四",11);
        PersonStatic perC = new PersonStatic("王五",12);
        PersonStatic.country = "中华人民共和国";
        System.out.println(perA.getInfo());
        System.out.println(perB.getInfo());
        System.out.println(perC.getInfo());
    }
}

此时会发现所有对象中的country属性的内容都发生了改变,所以这是一个公共属性,而此时的内存关系图如下:

但是对于static属性的访问需要注意一点:由于其本身是一个公共属性,所以理论上可以通过对象进行访问,但是最好的方法是通过所有对象的最高代表(类)来进行访问。所以static属性可以由类名称直接调用。

static属性虽然定义在类之中,但是其并不受到类实例化对象的控制。static属性可以在没有实例化对象的时候使用。

范例:不产生实例化对象调用static属性。

class PersonStatic {
    private String name;
    private int age;
    static String country="中华民国";
    public PersonStatic(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getInfo(){
        return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + this.country;
    }
}
public class staticJava {
    public static void main(String[] args) {
        System.out.println(PersonStatic.country);
        PersonStatic.country = "中华人民共和国";
        PersonStatic perA = new PersonStatic("张三",10);
        System.out.println(perA.getInfo());
    }
}

在以后进行类设计的时候首选的一定是非static属性,而考虑到公共信息存储的时候才会使用到static属性,95%的时候考虑的都是非static属性。非static属性必须在实例化对象产生之后才可以使用,而static属性可以在没有实例化对象产生的情况下直接通过类名称进行调用。

Static定义方法

static关键字也可以进行方法的定义,static方法的主要特点在于,其可以直接由类名称在没有实例化对象的情况下进行调用。

范例:定义static方法

class PersonStatic {
    private String name;
    private int age;
    private static String country="中华民国";
    public PersonStatic(String name,int age){
        this.name = name;
        this.age = age;
    }

    public static void setCountry(String c){ //static方法
        country = c;

    }
    public String getInfo(){
        return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + this.country;
    }
}
public class staticJava {
    public static void main(String[] args) {
        PersonStatic.setCountry("中华人民共和国");

        PersonStatic perA = new PersonStatic("张三",10);
        System.out.println(perA.getInfo());
    }
}

这时对于程序而言方法就有了两种:static方法、非static方法,这两个方法之间在调用上就有了限制。

  • static方法只允许调用static属性或static方法。
  • 非static方法允许调用static属性或static方法。
  • static方法中不能用this,本来就可以通过对象访问,
  • 非static方法中可以用this。this–>当前对象

所有的static属性和方法都可以在没有实例化对象的前提下使用,而所有的非static对象必须要有实例化对象的情况下使用。

如果说现在可以理解这个限制,那么对于之前的方法定义就可以得出新的结论:当前定义的方法都是在朱磊中定义的,并且由主方法直接调用

public class JavaDemo{
    public static void main(String[] args){
        print();
    }
    public static void print(){
        System.out.println("www.studyzzz.top");
    }
}
public class JavaDemo{
    public static void main(String[] args){
        new JavaDemo().print();
    }
    public void print(){
 //static方法不可以直接调用非static方法 可以通过实例化JavaDemo类对象之后才可以调用print普通方法
        System.out.println("www.studyzzz.top");
    }
}

static定义的方法或者是属性都不是你代码编写之初所需要考虑的内容,只要在回避实例化对象调用并且描述公共属性的情况下才会考虑使用static定义的方法或属性。

Static应用

为了加强理解,下面做两个简单的程序来进行static应用的提示。

范例:编写一个程序类可以石冼实例化对象个数的统计,每一次创建新的实例化对象都可以实现一个统计操作。

  • 此时可以单独创建一个static属性,因为所有对象都共享同一个static属性,那么在构造方法中可以实现数据的统计处理。
class Book{
    private String title;
    private static int count = 0;
    public Book(){}
    public Book(String title){
        this.title = title;
        count ++;
        System.out.println("第"+ count + "本新的图书创建出来");
    }
}
public class JavaDemo{
    public static void main(String[] args){
        new Book("Java"); new Book("JSP"); new Book("Spring");
    }
}

范例:实现属性的自动命名处理

  • 如果现在传递了title属性,就使用传递的属性内容,而如果没有传递title内容,则自动采用“NOTITLE-编号”进行该属性内容的定义。
class Book{
    private String title;
    private static int count = 0;
    public Book(){}
    public Book(String title){
        this.title = title;
        count ++;
        System.out.println("第"+ count + "本新的图书创建出来");
    }
    public String getTitle(){
        return this.title;
    }
}
public class JavaDemo{
class Book{
    private String title;
    private static int count = 0;
    public Book(){
        this("NOTITLE - " + count++);
    }

    public Book(String title){
        this.title = title;
        //System.out.println("第"+ count + "本新的图书创建出来");
    }
    public String getTitle(){
        return this.title;
    }
}
public class JavaDemo{
    public static void main(String[] args){
        System.out.println(new Book("Java").getTitle());
        System.out.println(new Book("JSP").getTitle());
        System.out.println(new Book("Spring").getTitle());
        System.out.println(new Book().getTitle());
        System.out.println(new Book().getTitle());
        System.out.println(new Book().getTitle());
    }
}

这样处理的好处是可以避免在没有设置title属性时内容为null的重复问题。

标签: