目录
6.Static类
6.1.静态static关键字概述
1.学生类(姓名,年龄,学号,所在教室); 学生对象(姓名,年龄,学号,所在教室);
2.对于姓名、年龄、学号来说,每一个对象都要自己独立的数据。
3.对于所在教室,这些对象都在同一个教室,应该共享同一份数据,而不是每个对象都要有教室属性。
4.因此,要求只在类中保存唯一一份,那所有本类的对象共享同一份数据。
5.一旦使用static关键字,那么该内容不再属于对象自己,而是属于类,所以本类所有对象共享该内容,谁都可以任意更改这个内容。
6.2.静态static关键字修饰成员变量
1.如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于所在的类。
多个对象共享这个数据,谁都可以修改该数据(为避免修改可以设置常量)。
2.下面是在学生类中将成员变量room设置为静态static,所有本类对象拥有同一份room数据。
将成员变量idCounter学号计数器设置为静态,在构造器中加入累加器并赋值给当前对象学号this.id,
这样每创建一个对象,虽然没有给学号赋值,也实现了学号自增。
Student学生类:
public class Student {
private String name;
private int age;
static String room;
private int id; //学号
//学号计数器,每当new一个新对象的时候,计数器++;学号自动
private static int discounters=0;
public Student(){this.id= ++idCounter;}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id= ++idCounter;
}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}
主类
public class Static1 {
public static void main(String[] args) {
Student one=new Student("zhangsan",20);
one.room="320教室";
System.out.println("姓名:"+one.getName()
+",年龄:"+one.getAge()
+",教室:" +one.room
+",学号:"+one.getId()); //学号使用累加器自动生成
Student two=new Student("lisi",25);
System.out.println("姓名:"+two.getName()
+",年龄:"+two.getAge()
+",教室:" +two.room
+",学号:"+two.getId()); //学号使用累加器自动生成
}
}
6.3.静态static关键字修饰成员方法
static关键字修饰成员方法:
1.一旦static修饰成员方法,那么就变为静态方法。
2.静态方法不属于对象,而是属于类。
3.若没有static关键字,那么必须首先创建对象才能使用方法,
但对于静态方法,可以通过对象进行调用,也可以直接通过类名调用。
推荐使用类名调用,可以明确知道是静态方法。
obj.methodStatic();这种写法在编译之后会被javac翻译为"类名.静态方法"
4.无论是成员变量还是成员方法,如果有static,都推荐使用类名进行调用。
5.对于本类当中的静态方法,可以省略类名
6.注意事项:
1.静态只能访问静态,不能直接访问非静态。成员方法可以访问静态。
原因是:内存中是【先】有静态内容,【后】有非静态内容。
2.静态方法中不能使用this.
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象。
而静态和对象没有关系,静态是属于类的。
public class MyClass {
int num; //成员变量
static int numStatic;//静态变量
//成员方法
public void method(){
System.out.println("这是一个普通的成员方法");
//成员方法可以访问成员变量
System.out.println(num);
//成员方法可以访问静态变量
System.out.println(numStatic);
}
//静态方法
public static void methodStatic(){
System.out.println("这是一个静态方法");
//静态方法可以放静态变量
System.out.println(numStatic);
/*静态方法不能直接访问非静态【重点】
* System.out.println(num);
* */
}
}
public class Static2 {
public static void main(String[] args) {
//1.对于非静态方法,首先创建对象
MyClass obj=new MyClass();
//然后才能调用方法
obj.method();
//2.对于静态方法,可以使用对象调用,推荐使用类名调用,可以明确知道是静态方法。
//不推荐。这种写法在编译之后会被javac翻译为"类名.静态方法"
obj.methodStatic();
//推荐使用
MyClass.methodStatic();
//3.对于本类当中的静态方法,可以省略类名
method();
Static2.method();//完全等效
}
public static void method(){
System.out.println("自己的方法");
}
}
6.4.静态static内存图
1.内存方法区中存放的是Student.class字节码文件,它有一个静态属性static String room,在方法区中还有一块静态区,存放静态成员,room数据就在静态区 中,当Student.room="101教室"时,就会在静态区给room赋值。
2.注意:Student.room="101教室"根据类名访问静态成员变量的时候,全程和对象没关系,只和类有关系。就算使用对象调用静态变量room,即one.room,编译时也会先翻译成Student.room,然后再去方法区中找到Student的静态room,然后在静态区找到room.
6.5.静态代码块
1.静态代码块:
1.静态代码块格式:
public class 类名{
static{
//静态代码块内容
}
}
2.特点:
1.当第一次用到本类时(通常是使用该类创建对象),静态代码块执行唯一的一次。
即只有第一次创建对象时执行静态代码块。当第二次创建对象时静态就不会再执行了。
Person son=new Person();
Person son1=new Person();
静态代码块在Person类中,在Static_Person类中创建对象
2.静态内容总是优先于非静态内容,所以静态代码块比构造方法先执行。
3.静态代码块典型用途:用来一次性地对静态成员变量进行赋值。
public class Person {
static{
System.out.println("静态代码块执行。");
}
public Person(){
System.out.println("构造函数执行。");
}
}
public class Static3_Person {
public static void main(String[] args) {
Person son=new Person();
Person son1=new Person();
/*输出:
静态代码块执行。
构造函数执行。
构造函数执行。*/
}
}