static修饰符
stati修饰符可用来修饰成员变量、成员方法和代码块
static变量
类的成员变量分两种:
类变量或静态变量:被static修饰的变量
实例变量:没有被static修饰的变量。
静态变量和实例变量的区别:
静态变量在内存中只有一个拷贝,运行java虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配,可以直接通过类名访问静态变量
实例变量,每创建一个实例,就会为实例变量分配一次内存。
public class Sample {
public static int number;
public void method() {
int x = number; //在类中直接访问静态变量
}
}
public class Sample2 {
public void method() {
int x = Sample.number; //在其他类中通过类名访问静态变量。
}
}
静态变量的两个作用
能被类的所有实例共享,可作为实例之间进行交流的共享数据。
public class Sample {
public static int i;
public void method() {
i = 123; //该方法不用return即可将i值传递出去
}
public static void main(String[] args) {
Sample s = new Sample();
s.method();
System.out.println("i="+i); //打印 i=123
}
}
如果类的所有实例都包含一个相同的常量属性,可把该属性定义为静态常量类型。
static final double PI=3.14;
static int MAX_INPUT_VALUE=220;
用于统计次数
private static int count; //投票次数
private static final int MAX_COUNT=100;//静态变量,最大投票数
import java.util.HashSet;
import java.util.Set;
public class Voter {
private static int MAX_COUNT=100; //最大投票数
private static int count; //投票数
private static Set<Voter> voters = new HashSet<Voter>();//存放所有已经投票的选民
private String name;
public Voter(String name) { //遍历voters集合
this.name = name;
}
//投票
public void voteFor() {
if(count==MAX_COUNT){
System.out.println("投票活动已结束");
return;
}
if(voters.contains(this)) {
System.out.println(name+":你不允许重复投票!");
}else {
count ++;
voters.add(this);
System.out.println(name+":感谢您投票!");
}
}
//打印投票结果
public static void printVoteResult() {
System.out.println("当前投票数为:"+count);
System.out.println("参与投票的选民名单如下:");
for(Voter voter : voters) {
System.out.println(voter.name);
}
}
public static void main(String[] args) {
Voter tom = new Voter("Tom");
Voter mike = new Voter("Mike");
tom.voteFor();
mike.voteFor();
Voter.printVoteResult();
}
}
static 方法
成员方法分类静态方法(类方法)和实例方法
静态方法不需要创建类的实例,可以直接通过类名来访问
public class Sample {
public static int add(int x,int y) {
return x+y;
}
}
public class Sample2 {
public void method() {
int result = Sample.add(1,2);
System.out.println("result:"+result);
}
}
1、静态方法可访问的内容
静态方法中不能使用this和super关键字,也不能直接访问所属类的实例变量和实例方法。但可以访问所属类的静态变量和静态方法。
public class Base {
protected int var1; //var实例变量
protected static int var2;
public void method1() {
var1++;
}
public static void method2() {
var2++;
}
}
public class Sub extends Base {
public static void method2() {
super.method(); //编译出错,静态方法中不能用super关键字。
.....
}
}
2、实例方法可以访问的内容
实例方法克制直接访问所属类的静态变量、静态方法、实例变量和实例方法。
class Sample {
protected int var1;
protected static int var2;
//实例方法
public void method1() {
var1++; //直接访问实例成员
var2++; //直接访问静态成员
method2(); //直接访问静态方法
}
//静态方法
public static void method2() {
//var1++; //编译错误,静态方法中不能直接访问实例变量
var2++;
//method1(); //编译错误,静态方法中不能直接访问实例方法
}
}
总结:实例方法可以直接访问所属类的静态成员、静态方法、实例变量和实例方法。但静态方法只能访问所属类的静态成员和静态方法。
3、静态方法必须被实现
静态方法用来表示某个类的所特有的功能,这种功能的实现不依赖于类的具体实例,也不依赖于它的子类。故当前类必须为静态方法提供实现。
一个静态方法不能被定义为抽象方法。
4、作为程序入口的main()方法是静态方法
在main()静态方法中不能直接访问类的实例变量和实例方法。
public class Sample {
int var;
public void method() {...}
public static void main(String[] args) {
Sample s = new Sample();
//只能通过类的实例的引用来访问实例变量和实例方法
s.var = 1;
s.method();
}
}
5、方法的字节码都位于方法区
static代码块
static代码块在类加载时执行,优于main方法、优于其他方法执行。且只会被执行一次。
若有多个代码块,则按顺序依次执行。
public class Sample {
static {
System.out.println("代码块1");
}
static {
System.out.println("代码块2");
}
public static void main(String[] args) {
System.out.println("main方法")
}
}
类的构造方法用于初始化类的实例,而类的静态代码块则可用于初始化类,给类的静态变量赋初始值。