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修饰的时候是可以在外部通过类直接访问调用的,只要可以在外部访问到这个类
相关推荐
易协同低代码6 分钟前
通达OA核心类库TD类深度解析
后端
Gopher_HBo8 分钟前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志1 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..1 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects1 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰1 小时前
一些基础和问题解决
后端
陈随易1 小时前
前端项目部署只要30秒
前端·后端·程序员
YIAN2 小时前
从零手写文件读取 MCP 服务:一文吃透 Model Context Protocol 全链路通信原理
前端·后端·mcp
Imchendiana2 小时前
《狂人日记NO.9》— 前后端一把梭,我的全栈实录
前端·后端
学渣超2 小时前
记一次分布式事务数据不一致的排查之旅:从超时到索引,层层剥茧
java·后端·架构