Java编程思想学习笔记二(1):static关键字的四种用法

本文详细介绍了Java中的static关键字,包括其修饰成员变量、成员方法及代码块的应用场景,并讲解了静态导入的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    前文中说到了static关键字,在Java中这是一个很重要的关键字,它有很多的用法,并且在某些特定的情况下使用可以优化程序的性能。本文学习static关键字的应用场景。在这之前了解变量的类型,变量按作用域分为成员变量和局部变量,成员变量也就是全局变量,它是在类中声明的,不属于类中任何一个方法。而局部变量是在类中的方法体中声明的,作用域只是这个方法体。接下来说一下static的作用。

一、修饰成员变量

    static最常用的功能就是修饰成员变量,被static修饰的成员变量称为静态变量也叫做类变量,它与普通的成员变量的区别是:对于静态变量内存中只有一个拷贝,JVM只为其分配一次内存,在加载类的过程中完成内存的分配。也就是说这个变量时属于这个类的,而其它任何这个类实例化的对象都拥有同一个拷贝。可以使用类名.变量的形式进行访问。而对于普通的成员变量,每创建一个对象就会产生一个拷贝,并且每创建一个对象就会分配一次内存。所以相比之下static常用于对象之前需要共享变量以及方便访问变量时使用。
public class TestStatic {
	private String name;
	private int age;
	public void print(){
		System.out.println("Name:" + name + "---Age:" + age);
	}
	public static void main(String[] args) {
		TestStatic ts1 = new TestStatic();
		TestStatic ts2 = new TestStatic();
		ts1.name = "zhangsan";
		ts1.age = 22;
		ts2.name = "lisi";
		ts2.age = 33;
		ts1.print();
		ts2.print();
	}
}
    以上代码是普通的成员变量的例子,对象ts1和ts2分别拥有着age 和 name两个成员变量的两个副本,彼此互相不影响,所以在实例化之后赋值,ts1能得到想要的值,ts2也能得到想要的值。有两个副本互不影响的意思就是他们指向两个不同的内存空间。
    
    我们修改一下成员变量age,将其用static修饰为静态成员变量。
public class TestStatic {
	private String name;
	private static int age;
	public void print(){
		System.out.println("Name:" + name + "---Age:" + age);
	}
	public static void main(String[] args) {
		TestStatic ts1 = new TestStatic();
		TestStatic ts2 = new TestStatic();
		ts1.name = "zhangsan";
		ts1.age = 22;
		ts2.name = "lisi";
		ts2.age = 33;
		ts1.print();
		ts2.print();
	}

}
    这时由于age变量变成了类变量,两个对象ts1和ts2公用一个相同的副本,所以ts1修改过后的值会被ts2重新修改。

    

    此外第二个示例代码中,静态成员变量使用了对象.变量的方式进行调用,这里编译器会给出警告,使用类名.方法之后警告就会解除。
    

二、修饰成员方法

    static的另一个作用是修饰成员方法,修饰成员方法的目的是使该方法可以通过类名.方法的形式进行调用,避免了创建对象的繁琐。同时对于存储空间来说,被修饰的方法没有本质上的区别,它与不被修饰的方法都属于类方法,每个对象调用的都是同一个方法。
public class TestStatic {
	private String name;
	private static int age;
	public static void print(){
		System.out.println("Name:" + name + "---Age:" + age);
	}
	public static void main(String[] args) {
		TestStatic ts1 = new TestStatic();
		TestStatic ts2 = new TestStatic();
		ts1.name = "zhangsan";
		ts1.age = 22;
		ts2.name = "lisi";
		TestStatic.age = 33;
		TestStatic.print();
		TestStatic.print();
	}

}
    将之前代码中的print方法改为使用static修饰之后,这个方法就可以不用对象.方法的形式调用了。

三、修饰代码块

    我们可以先看一下对象的初始化过程:
class Load {
	public Load(String msg){
		System.out.println(msg);
	}
}
public class TestStatic{
	Load ld1 = new Load("普通变量1");
	Load ld2 = new Load("普通变量2");
	static Load ld3 = new Load("静态变量3");
	static Load ld4 = new Load("静态变量4");
	public TestStatic(String msg){
		System.out.println(msg);
	}
	public static void main(String[] args) {
		TestStatic ts = new TestStatic("TestStatic 初始化");
	}
}
    在类TestStatic中,我们初始化了两个普通成员变量和两个静态成员变量,并在main函数开始的时候初始化了TestStatic对象。结果如下:
    
    静态成员变量最先被初始化,并且按照执行的先后顺序进行初始化。其次初始化的是成员变量,最后初始化的是构造方法。所以在创建一个对象的时候,最先被初始化的是静态成员变量。
    在看另外一个调用了静态方法的例子:
class Load {
	public Load(String msg){
		System.out.println(msg);
	}
}
public class TestStatic{
	Load ld1 = new Load("普通变量1");
	Load ld2 = new Load("普通变量2");
	static Load ld3 = new Load("静态变量3");
	static Load ld4 = new Load("静态变量4");
	public TestStatic(String msg){
		System.out.println(msg);
	}
	public static void staticFunc(){
		System.out.println("静态方法");
	}
	public static void main(String[] args) {
		TestStatic.staticFunc();
		System.out.println("@@@@@@@@@");
		TestStatic ts = new TestStatic("TestStatic 初始化");
	}
}
    我们在创建对象之前先调用了静态方法,结果如下:
    
    我们可以看到,静态成员的初始化发生在创建对象之前,确切的说是在调用静态方法之前就已经被初始化了。并且,当我们创建对象的时候,原本被初始化过的静态成员变量跟静态方法没有再次被初始化。
    这时我们的static的作用就是,修饰一段都需要被修饰为static的域。被static修饰的代码域,域中所有的内容都被当成static变量,且优先初始化。
class Load {
	public Load(String msg){
		System.out.println(msg);
	}
}
public class TestStatic{
	Load ld1 = new Load("普通变量1");
	Load ld2 = new Load("普通变量2");
	static Load ld3;
	static Load ld4;
	static{
		ld3 = new Load("静态变量3");
		ld4 = new Load("静态变量4");
	}
	
	public TestStatic(String msg){
		System.out.println(msg);
	}
	public static void staticFunc(){
		System.out.println("静态方法");
	}
	public static void main(String[] args) {
		TestStatic.staticFunc();
		System.out.println("@@@@@@@@@");
		TestStatic ts = new TestStatic("TestStatic 初始化");
	}
}
    修改之前的代码将静态成员变量放在由static修饰的域中,结果如下:
    
与分开修饰结果相同。

四、静态导入

    前三种是比较常用的方式,最后一种不太常用,但是在《Java编程思想》第三章第一节用到了一点,就是在JDK1.5之后加入的新功能,可以导入一个带有静态方法的静态包,从而可以在当前类中直接调用包中的静态方法,就好像是自己的方法一样。
先在一个包中创建一个类并定义一个静态方法:
package com.chenxyt.java.test;
public class Printer {
	public static void print(String msg){
		System.out.println(msg);
	}
}
然后在另一个包中用import static 导入这个类:
package com.chenxyt.java.practice;
import static com.chenxyt.java.test.Printer.*;
public class TestStatic{
	public static void main(String[] args) {
		print("This is TestStatic");
	}
}
运行:
    

五、总结

    static是Java语言中的一个很重要的关键字,主要用途有三个方面修饰成员变量,修饰成员方法以及修饰代码块。使用static修饰的成员变量在类加载的时候就已经被初始化了,它属于类变量,不属于某个对象,所有该类的实例化对象拥有同一个静态成员变量副本,常用的用途可以用它来做计数器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值