Java学习手册:static


一、static关键字的作用

static关键字主要有两种作用:第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二,实现某个方法或属性与类而不是对象关联在一起,也就是说,在不创建对象的情况下就可以通过类来直接调用方法或使用类的属性。具体而言,在Java语言中,static主要有4种使用情况:成员变量成员方法代码块内部类


二、static关键字

①由static修饰的变量称为静态变量,也称类变量。

②静态变量定义位置在所有方法之外。

③静态变量与静态方法都是在类从磁盘加载至内存后被创建,与类同时存在,同时消亡。

④静态变量又称类的成员变量,在类中是全局变量(Java没有全局变量和全局函数),可以被类中的所有方法调用。

⑤静态变量的值由JVM自动初始化
整型→0,布尔型→false,浮点型→0.0,字符串型→null,字符型→Unicode编码为0的字符(该字符不可见)


三、static成员变量

虽然Java语言中没有全局的概念,但可以通过static关键字来达到全局的效果。

Java类提供了两种类型的变量:用static关键字修饰的静态变量和不用static关键字修饰的实例变量。

静态变量属于类,在内存中只有一个复制(所有实例都指向同一个内存地址),只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使用了。对静态变量的引用有两种方式,分别为”类,静态变量“和”对象.静态变量“

实例变量属于对象,只有对象被创建后,实例变量才会被分配空间,才能被使用,它在内存中存在多个复制。只能用”对象.实例变量“的方式来引用

package com.haobi.staticdemo;
/*
 * static成员变量
 */
public class MemberVariable {
	public static int staticInt = 0;
	public int noStaticInt = 0;
	public static void main(String[] args) {
		MemberVariable mv = new MemberVariable();
		System.out.println("对象.静态变量:"+mv.staticInt);
		System.out.println("类.静态变量:"+MemberVariable.staticInt);
		System.out.println("对象.实例变量:"+mv.noStaticInt);
		System.out.println("-----对静态变量和实例变量分别+1-----");
		mv.staticInt++;//静态变量自增
		mv.noStaticInt++;//实例变量自增
		MemberVariable mv1 = new MemberVariable();
		System.out.println("对象.静态变量:"+mv1.staticInt);
		System.out.println("类.静态变量:"+MemberVariable.staticInt);
		System.out.println("对象.实例变量:"+mv1.noStaticInt);
	}
}
//程序输出结果如下:
对象.静态变量:0.静态变量:0
对象.实例变量:0
-----对静态变量和实例变量分别+1-----
对象.静态变量:1.静态变量:1
对象.实例变量:0

由上述示例可以看出,静态变量只有一个,被类拥有,所有对象都共享这个静态变量,而实例对象是与具体对象相关的。

注:在Java语言中,不能在成员函数内部及方法体中定义static变量


四、static成员方法

Java类提供了两种类型的方法:static方法和非static方法。static方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来之后才可以被使用。

一般方法在调用时,需要隐式的传递对象的引用(this),static在调用时,无具体的对象,所以没有隐式的this传递。static方法的作用在于提供一些”工具方法“和”工厂方法“。

static方法不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法,因为当static方法被调用时,这个类的对象可能还没有创建,即使已经创建了,也无法确定调用哪个对象的方法。同理,static方法也不能访问非static类型的成员(当前对象的属性和方法),但是非static方法可以访问static成员。

用public修饰static变量和方法本质上都是全局的,若在static变量前用private修饰,则表示这个变量可以在类的静态代码块或者类的其他静态成员方法中使用,但是不能在其他类中通过类名来直接引用。

注:非static声明的方法可以去调用static声明的属性或方法。但是static声明的方法是不能调用非static类型声明的属性或方法。


五、static代码块

static代码块(静态代码块)在类中是独立于成员变量和成员函数的代码块。它不在任何一个方法体内,JVM加载类时会执行static代码块,如果有多个static代码块,JVM将会按顺序来执行。static代码块经常被用来初始化静态变量(静态资源:图片、音频…)。需要注意的是,static代码块只能被执行一次。

package com.haobi.staticdemo;
/*
 * static代码块
 */
public class StaticBlock {
	private static int a;
	static {
		StaticBlock.a = 4;
		System.out.println(a);
		System.out.println("static block is called");
	}
	public static void main(String[] args) {
		
	}
}
//程序输出结果如下:
4
static block is called

六、static内部类

static内部类是指被声明为static的内部类,它可以不依赖于外部类实例对象而被实例化,而通常内部类需要在外部实例化后才能实例化。静态内部类不能与外部类有相同的名字。不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法(包括私有类型)。

package com.haobi.staticdemo;
/*
 * static内部类
 */
public class StaticInnerClass {
	static int n = 5;
	static class Inner{
		void getAttr() {
			System.out.println("Inner:StaticInnerClass.n="+n);
		}
	}
	public static void main(String[] args) {
		StaticInnerClass.Inner sic = new StaticInnerClass.Inner();
		sic.getAttr();
	}
}
//程序输出结果如下:
Inner:StaticInnerClass.n=5

注:只有内部类才能被定义为static


七、static与final结合使用表示什么意思?

答:在Java语言中,static关键字常与final关键字组合使用(二者前后顺序不限),用来修饰成员变量与成员方法,有点类似于C/C++语言中的”全局常量“。对于变量,若使用static final修饰,则表示一旦赋值,就不可更改,并且可通过类名访问,static final修饰的成员变量称为常量,必须声明同时初始化,不可被改变。对于方法,若使用static final修饰,则表示该方法不可覆盖,并且可以通过类名直接访问。

注:static final常量会在编译期被替换,如下述代码所示:

package com.haobi;
class Foo{
	public static final int Num1 = 100;//(1)常量
	public static int Num2 = 100;//(2)静态变量
}
public class Test {
	public static void main(String[] args) {
		System.out.println("Foo.Num1:"+Foo.Num1);
		System.out.println("Foo.Num2:"+Foo.Num2);
	}
}
//程序输出结果如下:
Foo.Num1:100
Foo.Num2:100

上述代码中,代码(1)在编译时直接替换为具体的数字,会替换为System.out.println(100);代码(2)的编译步骤如下:①加载Foo.class到方法区②将Num2存放在方法区③去方法区中获取Num2的值并输出。


八、static关键字是什么意思?Java中是否可以覆盖(override)⼀个private或者是static的⽅法?

“static”关键字表明⼀个成员变量或者是成员⽅法可以在没有所属的类的实例变量的情况下被访问。

Java中static⽅法不能被覆盖,因为⽅法覆盖是基于运⾏时动态绑定的,⽽static⽅法是编译时静态绑定的。static⽅法跟类的任何实例都不相关,所以概念上不适⽤。


九、是否可以在static环境中访问⾮static变量?

static变量在Java中是属于类的,它在所有的实例中的值是⼀样的。当类被Java虚拟机载⼊的时候,会对static变量进⾏初始化。如果你的代码尝试不⽤实例来访问⾮static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值