一万小时学编程:Static用法理解加例子

一万小时学编程系列

Static用法详解



前言

Java关键字static用途非常广泛,但很多人并没有深入理解它的内涵,今天我们通过这篇文,用大白话加实例来带大家深入了解一下static。


一、怎么理解static(静态)?

1.举例理解静态

如何理解Java中的静态变量?静态方法呢?首先我们捋一下Java中类和对象的关系:类是对某一类具有共同特征的事物的抽象,对象是根据类产生出的具体实例。举个栗子:对于一个类Student而言,有两个实例对象student1,student2.对于这两个对象而言,他们有自己的属性,年龄,班级,性别,姓名等,这些都是Student类有的属性,而每个对象有可能是不同也有可能是相同的,所以认为这是动态变量,而有的属性,比如他们都是中国人,那么这个属性是不可变的,称为类变量,也叫静态变量,而可变变量称为实例变量,也就是非静态变量。总结一下:静态是属于类的属性,不可变,非静态属于对象的属性,可变。

2.什么时候使用静态

静态主要修饰成员变量和成员方法。
什么时候使用静态变量?
当类中出现所有对象都共有的数据时,该字段就可以定义成静态的。比如上面例子里Student类的中国人这个属性就可以定义为静态变量。
什么时候使用静态方法?
当这个方法内部没有使用到非静态数据时(对象特有数据),那么该方法就是静态方法。像工具类XxxUtils中的工具类基本都是静态的,可以直接调用。

3.静态的特性

静态的特点:

  • 随着类的加载而加载,静态和类一同加载,优先于对象的加载。
  • 静态被所有的对象共享
  • 静态可以直接被类名调用,也可以被对象调用

静态的使用注意事项:

  • 静态方法只能访问静态成员(属性和方法),不能访问非静态成员。
  • 非静态方法可以访问静态成员,也可以访问非静态成员。
  • 因为静态方法先于对象而存在,所以静态方法中不能有this,super关键字。

静态的利弊:

  • 利:对于所有对象共有数据可以使用静态,节省空间,直接用类名调用。
  • 弊:静态随着类存在,所以其生命周期长,访问有局限性,只能访问静态。

二、静态的使用

1.static定义属性

我们来看一个图书的操作类,其中所有图书的出版社都是清华出版社:

package com.lxg.test
class Book{
      private String title;
      private double price;
      String pub="清华大学出版社";
      public Book(String title,double price){
             super();
             this.title=title;
             this.price=price;
      }
      public String getInfo(){
              return "书名:"+this.title+",价格:"+this.price+",出版社:"+this.pub;
      }
}
public class TestDemo{
       public static void main(String[] args){
               Book a=new Book("Java开发",10.2);
               Book b=new Book("Android开发",11.2);
               Book c=new Book("Oracle开发",12.2);
               System.out.println(a.getInfo());
               System.out.println(b.getInfo());
               System.out.println(c.getInfo());
       }
}

运行结果:

书名:Java开发,10.2,出版社:清华大学出版社
书名:Android开发,11.2,出版社:清华大学出版社
书名:Oracle开发,12.2,出版社:清华大学出版社

内存分配图:
在这里插入图片描述
可以看出pub这条属性封装在每个对象的内存里,这样很占内存,大家设想一下,如果要编程北京大学出版社,就需要每个对象去修改,简直太难了。
既然每个Book类对象的pub内容都是一样的,那么应该将其定义为一个共享属性,即所有对象共享的pub静态属性。

static String pub="清华大学出版社";

这时候类在主方法中直接调用Book.pub="北京大学出版社"就可以全部改变了,我们来看一下此时的内存分配图:
在这里插入图片描述

2.static定义方法

用static定义的方法称为静态方法,对象和类都可以直接调用

package com.lxg.test
class Book{
      private String title;
      private double price;
      private static String pub="清华大学出版社";
      public Book(String title,double price){
             super();
             this.title=title;
             this.price=price;
      }
      public static void setPub(String p){
             pub=p;
      }
      public String getInfo(){
              return "书名:"+this.title+",价格:"+this.price+",出版社:"+this.pub;
      }
}
public class TestDemo{
       public static void main(String[] args){
               Book.setPub("北京大学出版社");
               Book a=new Book("Java开发",10.2);
               Book b=new Book("Android开发",11.2);
               Book c=new Book("Oracle开发",12.2);
               System.out.println(a.getInfo());
               System.out.println(b.getInfo());
               System.out.println(c.getInfo());
       }
}

运行结果:

书名:Java开发,10.2,出版社:北京大学出版社
书名:Android开发,11.2,出版社:北京大学出版社
书名:Oracle开发,12.2,出版社:北京大学出版社

我们前面讲过,static定义的方法和变量,可以在没有实例化对象的时候使用;而非static定义的属性和方法,必须实例化对象后才可以调用。所以一个类中如果没有任何属性,建议可以将方法定义为static。而实际开发中优先考虑非static方法和非static属性。

3.Java主方法

我们先观察一下Java中主方法的组成:

public static void main(String args[]){...}

分析一下:

  • public:表示公共访问权限
  • static:此方法由类名称直接调用
  • void:主方法是程序执行的开始
  • main:系统规定的一个方法名称,执行类的时候默认找到此名称,不能修改
  • String args[]:表示程序运行时传递的参数,通过字符串接受。

对于主方法中对静态方法的调用我们再举个栗子:

  • 在static方法中直接调用static方法。
package com.lxg.demo
public class TestDemo{
       public static void main(String args[]){
               print();
       }
       public static void print(){
                System.out.println("Hello  World!");
       }
}

运行结果:

Hello  World!
  • 在static方法中直接调用非static方法
package com.lxg.demo
public class TestDemo{
       public static void main(String args[]){
               print();
       }
       public  void print(){
                System.out.println("Hello  World!");
       }
}

运行结果:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Cannot make a static reference to the non-static method print() from the type TestDemo

    at com.wz.thisdemo.TestDemo.main(TestDemo.java:5)
  • 在static中用实例化对象调用非static方法
package com.lxg.demo
public class TestDemo{
       public static void main(String args[]){
               new TestDemo().print();
       }
       public  void print(){
                System.out.println("Hello  World!");
       }
}

运行结果:

Hello World!

总结:Static方法可以类调用Static方法,类不能调用非static,非static方法要用实例化对象调用。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了static的理解和使用,而static在内存层面有更深刻的含义等待大家去挖掘,本文是参考两位大佬的博客写的,有不足的地方欢迎指正,如果本文对你有所帮助的话请关注点赞,你的鼓励是我最大的动力。
@志见:Java关键字static详解https://blog.csdn.net/wei_zhi/article/details/52767651
@嗑嗑嗑嗑瓜子的猫:大白话系列之 —— 一语点破Java中的静态static关键字https://blog.csdn.net/ju_362204801/article/details/90738966

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值