java之静态变量和方法(类变量、类方法)

1 类变量

1.1 简要介绍

由一个简单的程序引出:

public class Example1 {
    int n;
    static int num = 10; //有 static 修饰
    //此时 num 即为一个类变量(静态变量),static 表示静态的
    //这个变量的最大特点是,它会被 Example 类的所有对象实例,共享
    public Example1(int n) {
        this.n = n;
    }
}

建立一个测试例:

public class Test {
    public static void main(String[] args) {
        //创建2个对象
        Example1 exam1 = new Example1(3);
        Example1 exam2 = new Example1(4);
        
        System.out.println(exam1.n);//输出3
        System.out.println(exam2.n);//输出4
        
        System.out.println(exam1.num);//输出10
        System.out.println(exam2.num);//输出10
        System.out.println(Example.num);//输出10
    }
}

​ 在上面的测试例中,我们创建了2个对象 exam1、exam2,每个对象在创建时都会独立的创建一个属于自己的属性 n, 而不会创建静态属性 num, 因为 num 是所有 Example 类的对象所共享的,n 是所有的对象独有的。


1.2 类变量的内存布局

  书接上回,既然类变量不会随着对象的创建而创建,那么类变量在内存中的存在形式是什么呢?

  关于静态变量存放的位置,主要有2种观点,一种说是在方法区,一种说是在堆区域,这和我们使用的jdk版本也有一定的关系。

  有感兴趣的读者,可以参考以下2篇博客:

  1. https://blog.youkuaiyun.com/x_iya/article/details/81260154/
  2. https://www.zhihu.com/question/59174759/answer/163207831

  对于本篇博客讨论的内容来说,我们需要记住的是:static 变量是所有对象共享的,不管 static 变量在哪里,共识是:

  1. static 变量是同一个类所有对象共享
  2. static 类变量,在类加载的时候就生成了,即类变量是随着类的加载而创建,所以即使没有创建对象实例也可以访问。

1.3 什么是类变量

1.3.1 定义

  类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取得的值都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量,相信看过上面类变量的内存布局会有更加深刻的认识。

1.3.2 类变量的定义语法

// 访问修饰符 static 数据类型 变量名;[推荐]
// static 访问修饰符 数据类型 变量名;

public static int n;
static public int m;

1.3.3 类变量的访问

// 类名.类变量名
// 对象名.类变量名 [静态变量的访问修饰符的访问权限和范围和普通属性是一样的]
Example1.num;
exam1.num;

  类变量是随着类的加载而创建,所以即使没有创建对象实例也可以访问。

public class Test1 {
    public static void main(String[] args) {
        //类变量是随着类的加载而创建,所以即使没有创建对象实例也可以访问。
        System.out.println(Example1.num);
    }
}

1.4 类变量使用的注意事项

  1. 什么时候需要类变量?

    当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量):比如:定义一个学生类,用来统计所有的学生需要交多少钱。

  2. 类变量与实例变量的区别。

    类变量是该类的所有对象共享的,而实例变量是每个对象独享的。

  3. 使用 static 进行修饰,称为类变量或者静态变量,否则称为实例变量/普通变量/非静态变量

  4. 类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,我们更推荐前一种。

  5. 实例变量不能通过 类名.类变量名 来进行访问,因为实例变量是每个对象所独有的。

  6. 类变量是在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了,就可以使用类变量了。

  7. 类变量的生命周期是随着类加载开始,随着类消亡而销毁。


2 类方法

2.1 基本介绍

  类方法也叫静态方法,形式如下:

// 访问修饰符 static 数据返回类型 方法名() { } [更为推荐使用]
// static 访问修饰符 数据返回类型 方法名() { }
public class Example2 {
    public static void f1() { }
    static public int f2() { }
}

  类方法的调用:

// 类名.类方法名
// 对象名.类方法名
public class Test2 {
    public static void main(String[] args) {
        Example2 a = new Example2();
        a.f1();// 对象名.类方法名
        Example2.f1();// 对象名.类方法名
    }
}


2.2 什么时候使用类方法

  1. 如果我们希望不创建实例,也可以调用某个方法(即当做工具来使用)。

在这里插入图片描述

​ 以上是 Math 类中的源码,方法功能为开方,可以看出这个方法是静态方法,所以我们在日常使用中,一般直接通过类名调用即可。Math.sqrt(9);

  1. 当我们开发自己的工具类时,可以将自己的方法做成静态的,方便调用。

  2. 当方法中不涉及到任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率。

    比如:工具类(utils)中的方法

    Mat 类、Arrays 类等

总结: 在实际开发中,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用,比如打印数组、排序等。


2.3 类方法使用的注意事项

  1. 类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区:

    • 类方法中无 this 的参数

    • 普通方法中隐含着 this 的参数

 public static void hi() {//静态方法,类方法
    //类方法中不允许使用和对象有关的关键字,
    //比如this 和 super。普通方法(成员方法)可以。
    //System.out.println(this.n1);
 }
  1. 类方法可以通过类名调用,也可以通过对象名调用。
Math.sqrt(9);//通过类名调用
Examle2 b = new Example2();
b.f1();//通过对象名调用

  1. 普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用。
  2. 类方法(静态方法)中,只能访问静态变量或着静态方法。
 class D {
     private int n1 = 100;
     private static int n2 = 200;
     
	 public void say() {//非静态方法,普通方法
	}
 	
     public static void hi() {
         System.out.println(n1);//访问非静态
         System.out.println(n2);//访问静态
     }
     //类方法(静态方法)中 只能访问 静态变量 或静态方法
    //口诀:静态方法只能访问静态成员.
     public static void hello() {
        System.out.println(n2);
        System.out.println(D.n2);
         //System.out.println(this.n2);不能使用
        hi();//OK
         //say();//错误,say()为非静态方法
	}
  1. 普通方法既可以访问非静态成员,也可以访问静态成员。

总结: 静态方法,只能访问静态的成员和静态的方法;非静态的方法,可以访问静态的成员和非静态的成员。(都必须遵守访问权限)


3 理解 main 方法

3.1 main方法的执行

  解释 main 方法的形式:public static void main(String[] args) { }

  1. main 方法是由虚拟机调用的
  2. java虚拟机需要调用类的 main() 方法,所以该方法的访问权限必须是 public
  3. javaz虚拟机在执行 main() 方法时不必创建对象,所以该方法必须是 static
  4. 该方法接收 String 类型的数组参数,该数组中保存执行 java 命令时传递给所运行的类的参数。
  5. java 执行的程序 参数1 参数2 参数3 …

在这里插入图片描述


3.2 注意事项

  1. 在 main() 方法中,我们可以直接调用 main 方法所在类的静态方法或静态属性。
  2. 但是,在 main 中,不能直接访问该类的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员。
public class Main {
    //静态的变量/属性
	private static String name="棐木";
 	//非静态的变量/属性
	private int n1=10000;
    
    //静态方法
    public static void hi() {
        System.out.println("我是静态方法hi");
    }
    
    //非静态方法
    public static void cry() {
        System.out.println("我是非静态方法cry");
    }
    
    public static void main(String[] args) {
        //可以直接使用 name
		//1. 静态方法main 可以访问本类的静态成员
		System.out.println("name=" + name);//访问静态属性
 		hi();//访问静态方法
 		//2. 静态方法main 不可以访问本类的非静态成员
		//System.out.println("n1=" + n1);//错误,不能访问非静态属性
		//cry();//不能访问非静态方法
 		//3. 静态方法main 要访问本类的非静态成员,需要先创建对象 , 再调用即可
		Main01 main01 = new Main01();
 		System.out.println(main01.n1);//ok
 		main01.cry()
    }
}

3.3 IDEA 中向 main 中传递参数

由以下程序说明:

public class CommandPara {
    public static void main(String[] args) {
        //输出args 数组
        for(int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }
}

  在 IDEA 中向 main 传参步骤:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

<think>首先,用户的问题是:“我想询问Java类方法变量是否等同于静态方法静态变量 请问Java 类方法变量是否与静态方法静态变量相同?” 我需要根据系统级指令来构建我的回答。关键点包括: - 使用中文回答。 - 所有行内数学表达式用$...$格式(但这个问题可能不涉及数学,所以可能不需要)。 - 独立公式用$$...$$格式(同样,可能不适用)。 - LaTeX语法正确(如果用到数学)。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用:用户提供了几个引用,我需要整合这些信息。 用户提供的引用: - [^1]: Java中的静态变量静态方法静态变量(static variable)有时也称为变量(class variable),它由的所有实例共享。对于的所有对象来说,静态变量只有一个副本。所以在一个对象中修改静态变量的值,同时也就修改了其他所有对象中该静态变量的值。保留字static是用来声明静态变量的修饰符。静态变量的内存空间是在程序第一次使用该变量所在的时分配的。在方法内声明的局部变量不能是静态的。 - [^2]: java 静态变量非静态_Java中静态静态变量之间的区别。2分享中A static variable acts as a global variable and is shared among all the objects of the class.非静态变量特定于创建它们的实例对象。 - [^3]: java 静态对象调用成员方法_Java学习笔记8---的静态成员变量与静态成员方法的访问与调用方式...。静态成员变量又称变量,静态成员方法又称类方法,它们统称为静态成员或成员。静态成员由static修饰,是属于整个的,所有的对象共享这些静态成员。不需要创建任何对象,静态成员在装载时就已初始化了,整个运行期间其内存位置不变,直到卸载。鉴于静态成员的这些特性,访问静态成员变量以及定义或调用静态成员方法时与非静态成员也有不同之处。 - [^4]: java静态代码块静态变量_Java中的静态变量静态方法与静态代码块。● 静态变量是一个引用。这种情况比较特殊,主要问题是由于静态变量是一个对象的引用,那么必须初始化这个对象之后才能将引用指向它。因此如果要把一个引用定义成static的,就必须在定义的时候就对其对象进行初始化。 从这些引用中,我可以总结出: - 静态变量(static variable)也称为变量(class variable),因为它们属于本身,而不是的实例。 - 同样,静态方法(static method)也称为类方法(class method)。 - 引用[^3]明确指出:“静态成员变量又称变量,静态成员方法又称类方法”。 所以,答案是:是的,Java类方法变量等同于静态方法静态变量。 现在,构建我的回答: 1. **结构清晰**:逐步解释。 - 先确认问题。 - 解释什么是静态方法静态变量。 - 解释为什么它们被称为类方法变量。 - 引用相关部分。 2. **使用中文**:整个回答用中文。 3. **生成相关问题**:在结尾添加相关问题部分。 4. **添加引用标识**:在回答中自然地添加引用标识。 回答大纲: - 开头直接回答:是的,Java类方法变量静态方法静态变量是相同的。 - 解释: - 静态变量变量)由static修饰符声明,属于本身,所有实例共享。 - 静态方法类方法)也由static修饰符声明,可以直接通过名调用,而不需要创建实例。 - 引用支持:引用[^1]、[^2]、[^3]都提到这一点。 - 例如,引用[^3]说:“静态成员变量又称变量,静态成员方法又称类方法”。 - 结尾添加相关问题。 相关问题想法: 1. 静态方法静态方法有什么区别? 2. 如何正确使用静态变量以避免并发问题? 3. 静态代码块在Java中的作用是什么? 4. 变量实例变量的主要区别是什么? 确保回答真实可靠:基于Java语言规范,静态成员属于级别。 最终回答结构: - 回答部分:清晰、分步骤。 - §§相关问题§§:列出3-4个相关问题。</think>是的,在Java中,类方法变量确实等同于静态方法静态变量。这是Java语言的核心特性之一,由`static`关键字定义。下面我将逐步解释原因相关细节,帮助你彻底理解这个问题。 ### 步骤1: 理解静态变量变量) - **定义特性**:静态变量使用`static`修饰符声明,例如`static int count;`。它被称为变量(class variable),因为它属于整个本身,而不是的任何特定实例。所有的对象共享同一个静态变量的副本。这意味着: - 如果在一个对象中修改静态变量的值,所有其他对象中的该变量也会同步更新。 - 静态变量的内存空间在首次加载时分配(例如,当程序第一次访问该时),并在整个程序运行期间保持不变,直到被卸载。 - 局部变量(在方法内声明的变量)不能是静态的,因为静态变量必须是级别的[^1]。 - **为什么等同于变量**:引用[^3]明确指出:“静态成员变量又称变量”,因为它由的所有实例共享,不需要创建对象即可访问。例如: ```java public class MyClass { static int classVariable = 0; // 变量静态变量) } ``` 这里,`classVariable`可以通过`MyClass.classVariable`直接访问,无需实例化对象。 ### 步骤2: 理解静态方法类方法) - **定义特性**:静态方法同样使用`static`修饰符声明,例如`static void myMethod() {...}`。它被称为类方法(class method),因为: - 它属于本身,而不是任何特定对象。可以直接通过名调用,如`ClassName.methodName()`。 - 静态方法不能访问非静态成员(变量方法),因为它不依赖于对象实例。相反,它只能操作静态变量或调用其他静态方法。 - 加载时初始化,与静态变量似,确保在程序运行早期可用[^3]。 - **为什么等同于类方法**:引用[^3]强调:“静态成员方法又称类方法”。例如: ```java public class MathUtils { static int add(int a, int b) { // 类方法静态方法) return a + b; } } ``` 这里,`add`方法可以通过`MathUtils.add(2, 3)`调用,无需创建`MathUtils`对象。 ### 步骤3: 关键区别常见误区 - **与非静态成员的对比**: - 非静态变量(实例变量)是对象级别的,每个对象有自己的副本。修改一个对象的实例变量不会影响其他对象[^2]。 - 非静态方法(实例方法)必须通过对象调用,并能访问实例变量。 - **为什么术语相同**:在Java官方文档社区中,“变量类方法”是“静态变量静态方法”的同义词,都强调它们属于而非实例。引用[^2]解释:静态变量作为全局变量共享于所有对象,而非静态变量特定于实例对象。 - **特殊注意事项**: - 如果静态变量是对象引用(如`static MyObject obj;`),必须在定义时或静态代码块中初始化,否则可能引发`NullPointerException`[^4]。 - 静态成员常用于工具(如`Math`中的方法)或共享配置,但过度使用可能导致并发问题,需谨慎设计。 ### 总结 Java类方法变量静态方法静态变量完全等同,都通过`static`关键字定义,并共享“属于而非实例”的核心特性。这种设计优化了内存使用访问效率,适用于全局状态或工具函数场景[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值