Java中将代表类范围信息的变量用关键字static修饰,保存在全局数据区,以便该类的所有实例进行共享.用static修饰的方法称为静态方法,又叫类方法(在静态方法里取不到this).
类变量和类方法与实例变量和方法的区别:
类变量和类方法:
①. 类的变量和类的方法都由static修饰
②. 类变量和类方法由该类产生的所有实例共享
③. 调用方式:
类名\对象名.静态变量
类名\对象名.静态方法
④. 即使没有创建该类的具体对象,类中的static类成员也会存在,可以通过以下方式调用:
类名.静态变量
类名.静态方法
因此,main()要用static修饰,因为可能类的对象没有创建起来,但仍可以调用该static方法
实例变量和方法:
①. 每一个实例拥有一份独立拷贝,因此每一个实例对象的数据是独立且唯一的
②. 调用方式:
对象名.实例方法
对象名.实例变量
注意事项:
①. static方法中不能直接调用非static的域或方法,必须通过对象名引用。典型的例子就是static void main()方
法,在这个static方法中可以看到,会创建任意的实例,然后通过这些实例来调用所属的非静态方法。
②. static方法可以不需要产生任何对象,就可通过类名来调用。
③. 非静态数据/函数和对象绑定。
④. 在static函数中直接取用非静态数据/函数,会产生语法错误。
static关键字的程序说明1:
创建一个Person类:
public class Person {
String name;
String sex;
int age;
//类变量
private static int count;
public static int getCount(){
return count;
}
public Person(String n,String s,int a){
this.name = n;
this.sex = s;
this.age = a;
count++;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
测试类如下:
public class testPerson {
public static void main(String[] args) {
Person p1 = new Person("张三", "男", 20);
System.out.print("count="+p1.getCount()+"\t");
System.out.print("count="+Person.getCount()+"\n");
Person p2 = new Person("Tom","M",50);
System.out.print("count="+p2.getCount()+"\t");
System.out.print("count="+Person.getCount()+"\n");
Person p3 = new Person("Mary","F",50);
System.out.print("count="+p3.getCount()+"\t");
System.out.println("\n通过类名和不同对象名访问静态变量count:");
System.out.print("count="+Person.getCount()+"\n");
System.out.print("count="+p1.getCount()+"\t");
System.out.print("count="+p2.getCount()+"\t");
System.out.print("count="+p3.getCount()+"\t");
}
}
测试结果如下:
count=1 count=1
count=2 count=2
count=3
通过类名和不同对象名访问静态变量count:
count=3
count=3 count=3 count=3
class StudentDemo {
static int num; // 类变量,保存在全局数据区,所有的对象共享
int number; // 实例变量,初始值为0,保存在heap中,每一个对象有一份独立的拷贝
int add1() {// add1()方法退出时,内存中的值可以保留
num = num + 1;
return num;
}
int add2() {// add2()方法退出时,内存中的值不能保留
number = number + 1;
return number;
}
}
// 测试类
public class stuDemo {
public static void main(String[] args) {
StudentDemo wang = new StudentDemo();
StudentDemo song = new StudentDemo();
StudentDemo li = new StudentDemo();
System.out.println("wang.num=" + wang.add1());
System.out.println("wang.number=" + wang.add2());
System.out.println("song.num=" + song.add1());
System.out.println("song.number=" + song.add2());
System.out.println("li.num=" + li.add1());
System.out.println("li.number=" + li.add2());
System.out.println("wang.num=" + wang.num + "\t" + "song.num="
+ song.num + "\t" + "li.num=" + li.num);
System.out.println("wang.number=" + wang.number + "\t" + "song.number="
+ song.number + "\t" + "li.number=" + li.number);
}
}
结果为:
wang.num=1
wang.number=1
song.num=2
song.number=1
li.num=3
li.number=1
wang.num=3 song.num=3 li.num=3
wang.number=1 song.number=1 li.number=1
静态代码块与非静态代码块的不同点:
①. 静态代码块在非静态代码块之前执行
②. 静态代码块—>非静态代码块—>构造方法
③. 静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次
④. 静态代码块只能在类中定义,独立于任何方法,不能定义在方法里。
⑤. 静态代码块里面新定义的变量都是局部变量,只能在本块内有效。
⑥. 静态代码块在类被加载时自动执行,而无论加载者是JVM还是其他的类。
⑦. 一个类中允许定义多个静态代码块,执行的顺序根据定义的顺序进行
⑧. 静态代码块只能访问类的静态成员,而不允许访问实例成员
静态代码块的程序说明,创建一个StudentDemo类:
public class staticBlock {
//类变量,即静态变量
private static int count;
//构造函数
public staticBlock(){
System.out.println("This is constructor funciton");
}
//顶一个静态代码块
static{
System.out.println("This is static block.");
count = 5;
}
//main方法
public static void main(String[] args) {
staticBlock s1 = new staticBlock();
System.out.println("This is main method");
System.out.println("count="+count);
}
}
测试结果为:
This is static block.
This is constructor funciton
This is main method
count=5