java静态变量&静态方法(类变量&类方法)

创建方法

  • 使用static关键字进行修饰

概念

  • static修饰过的成员变量或者成员方法,就叫静态变量(类变量)、静态方法(类方法),因为它属于类本身的,而不是属于任何一个被实例的对象:

    • 访问 :想要访问静态变量、静态方法,可以通过类名直接访问,也可以通过某一个被实例的对象访问 (底层原理是因为对象也是类创建的通过对象访问java知道我们要找谁),而在java中未被static修饰过的成员变量,就只能通过对象来访问,因为未被static修饰的成员变量,只有示例化对象之后才真实存在,此时为被static修饰的变量只属于对象;
    • 如果main函数也在类中,可以在main函数中直接改变类中的静态变量
    • 静态变量、静态方法是该类所有实例对象共同的变量(方法);
    • 静态变量只会在类被加载的时候被初始化一次;
    • 静态方法里不能直接访问成员变量、成员方法,因为成员变量和方法属于具体的对象。
java 复制代码
	//错误示例
	public class Car {
	    int speed; // 非静态成员变量

	    public static void printSpeed() {
	        System.out.println(speed); // 错误!静态方法不能直接访问非静态成员变量
	    }
	}

	//正确示例
	public class Car {
	    int speed; // 非静态成员变量
	
	    public static void printSpeed(Car car) {
	        System.out.println(car.speed); // 正确!通过对象实例访问非静态成员变量
	    }
	}
	//正确示例
	public class Car {
	    static int maxSpeed = 200; // 静态成员变量
	    public static void printMaxSpeed() {
	        System.out.println(maxSpeed); // 正确!静态方法可以直接访问静态成员变量
	    }
	}

代码实操

  • 将类Student中的Number设置为静态变量,并在main方法中访问,同时测试是否可以通过类访问普通变量name,顺便试一下main方法在类中,直接改变类变量的情况,如下方代码所示:
java 复制代码
package demoPackage.hello.world;   
public class Student {  
    private String name;  
  
    private int age;  
  //将成员变量number修饰为静态
    private  static  int number;  
  
    public  String getName(){  
        return name;  
    }  
  
    public int getAge() {  
        return age;  
    }  
	//将成员方法getNumber修饰为静态
    public static int getNumber() {  
        return number;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public void setAge(int age) {  
        this.age = age;  
    }  
	//将setNumber修饰为静态
    public static void setNumber(int number) {  
        Student.number = number;  
    }  
  
    public static void main(String[] args) {  
        Student Xiaoming = new Student();  
        Xiaoming.setName("小明");  
        Xiaoming.setNumber(10);  
		//我们通过对象间接访问了类中的静态方法
  
        Student Xiaohong = new Student();  
        Xiaohong.setName("小红");  
		
		
		//打印出对象中的属性,发现我们刚刚的操作是成功的
	    System.out.println("学生"+ Xiaoming.getName() + "的学号是:" + Xiaoming.getNumber());//学生小明的学号是:10  
        System.out.println("学生"+ Xiaohong.getName() + "的学号是:" + Xiaohong.getNumber());//学生小红的学号是:10  
        
        Xiaohong.setNumber(12);  //我们通过对象间接访问了类中的静态方法

		//发现对象xiaoming和xiaohong都改变了,说明setNumber是在类中的,会共同改变Student类中所有对象的静态属性值number
        System.out.println("学生"+ Xiaoming.getName() + "的学号是:" + Xiaoming.getNumber());//学生小明的学号是:12  
        System.out.println("学生"+ Xiaohong.getName() + "的学号是:" + Xiaohong.getNumber());//学生小红的学号是:12  
  
        Student.number = 13;  //我们发现通过类修改静态成员变量也会影响对象的属性,因为对象共同拥有该静态成员变量
//      Student.name = "小红";//未被static修饰的变量无法通过类访问,因为name是属于对象的属性
        System.out.println("学生"+ Xiaoming.getName() + "的学号是:" + Xiaoming.getNumber());//学生小明的学号是:13  
        System.out.println("学生"+ Xiaohong.getName() + "的学号是:" + Xiaohong.getNumber());//学生小红的学号是:13  

		number = 15;  //直接在该类的main中可以修改类中的static属性
System.out.println("学生"+ Xiaoming.getName() + "的学号是:" + Xiaoming.getNumber());//学生小明的学号是:15  
System.out.println("学生"+ Xiaohong.getName() + "的学号是:" + Xiaohong.getNumber());//学生小红的学号是:15
    }  
}
  • 静态方法
java 复制代码
package demoPackage.hello.world;  
  
public class Student {  
    private String name;  
  
    private int age;  
  
    private  static  int number;  
  
    public  String getName(){  
        return name;  
    }  
  
    public int getAge() {  
        return age;  
    }  
  //将getNumber方法设置为静态方法
    public static int getNumber() {  
        return number;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public void setAge(int age) {  
        this.age = age;  
    }  
  
    public static void setNumber(int number) {  
        Student.number = number;  
    }  
  
    public static void main(String[] args) {  
        Student Xiaoming = new Student();  
        Xiaoming.setName("小明");  
        Xiaoming.setNumber(18);  
        System.out.println("学生"+ Xiaoming.getName() + "的学号是:" + Xiaoming.getNumber());//学生小明的学号是:18  
        System.out.println("学生"+ Xiaohong.getName() + "的学号是:" + Xiaohong.getNumber());//学生小红的学号是:18   
		//setName();//发现无法直接调用setName,ide表示找不到该方法,并建议将setName设为静态
        setNumber(18);//发现可以直接调用被static修饰的方法
    }  
}

在main.java试着用类访问方法的方式调用被static修饰的setNumber():

java 复制代码
package demoPackage;    
import demoPackage.hello.world.Student;  
  
public class main {  
    public static void main(String[] args) {    
        Student stu = new Student();  
        stu.setName("xiaolv");  
        Student.setNumber(16);  
        System.out.println("学生"+ stu.getName() + "的学号是:" + stu.getNumber());//学生xiaolv的学号是:16 
        //setNumber() 
        //试着直接调用发现无法运行,提示我们没有该方法,因为这个main方法不在静态方法setNumber所在的类中,而是在主类main中
    }  
}
  • 此时我们通过代码文件的外观树可以发现,当方法被static修饰的时候是可以在外部通过类直接访问调用的,只要可以在外部访问到这个类
相关推荐
滴滴答答哒8 分钟前
ASP.NET Core + FaceRecognitionDotNet 人脸识别实战:DI 单例、特征向量持久化与 1:N 比对
后端·asp.net
captain3763 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
IT_陈寒4 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
泡海椒4 小时前
05-雷达图多维画像-信用评级多维画像
后端
王中阳Go4 小时前
5.27 分钟干完后端和全部测试:一场三小时笔试的五个失分点,四个不在代码上
大数据·数据库·人工智能·后端·大语言模型
大哥43094 小时前
Modbus 的"字序":一个配错就变成天文数字,或者干脆变成 0
后端
岩钧4 小时前
New API 源码解析:一个生产级 AI 网关的架构与实现
后端
学到老活到老4 小时前
第 24 集:配置文件写了 80,Spring Boot 为什么读到 90?
java·后端·spring
用户360055579004 小时前
Kestrel_VLLM - 25 · 全注意力层设备化、整层对拍与访存粒度
后端
yliucherish4 小时前
从零实现一个 SQL 注入检测引擎:报错注入与布尔盲注的误报控制
后端