static修饰符
静态域
- 如果将域定义为static,每个类中只有一个这样的域。而每一个对象对于所有实例域却都有自己的一份拷贝。
- 无论你实例化多少个对象,每个对象都有自己的实例域。但是静态域就只有一个,即使没有任何实例化对象,他也存在。它属于类,而不属于任何独立的对象。
以下是例子,代码如下:
public class Student {
//创建一个实例域;
public String Name;
public int Age;
public int id;
//创建一个静态域;
public static String classroom = "北京101班";
}
public class Staticdemo {
public static void main(String[] args) {
System.out.println("静态域(班级):");
System.out.println(Student.classroom);
Student student1 = new Student();
student1.Name = "洪七公";
student1.Age = 103;
student1.id = 001;
Student student2 = new Student();
student2.Name = "欧阳锋";
student2.Age = 73;
student2.id = 002;
Student student3 = new Student();
student3.Name = "段智兴";
student3.Age = 84;
student3.id = 003;
System.out.println("=====================");
System.out.println(student1.Name + "所在班级:" + student1.classroom);
System.out.println("========洪七公调到102班=============");
student1.classroom = "北京102班";
System.out.println(student1.classroom);
System.out.println("静态域(班级):" + Student.classroom);
}
}
运行结果
这个代码理解的话,就是实例化出来student1、student2、student3都有自己的实例域即Name、Age、id属性,而classroom因为使用了static修饰符,所以属于Student类,为student1、student2、student3所共享,无论是谁修改都会全部修改。
静态方法、静态变量
-
一旦使用了 static 修饰成员方法,那么就成为了静态方法。静态方法不属于对象,属于类。
-
如果没有static关键字,那么就必须首先创建对象,然后通过对象去调用。
如果有static关键字,那么就不需要创建对象,直接通过类名称去调用。 -
无论是成员变量,还是成员方法。如果用static修饰,都推荐使用类名称来调用。
静态变量:类名称.静态变量
静态方法:类名称.静态方法()
public class Student {
public static void methodStatic(){
System.out.println("静态方法");
}
}
public class StudentDemo{
public static void main(String[] args) {
//对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名称来调用。
//不建议使用,这种写法在编译之后也会被javac翻译成为“类名称.静态方法”
new Student().methodStatic(); //通过创建对象调用methodStatic()方法。
//建议使用。
Student.methodStatic(); //通过对象名直接调用methodStatic()方法。
functionstatic(); //在本类中使用本类的静态方法,可以省略类名称。
new Staticdemo02().functionstatic(); //两者相等
}
public static void functionstatic(){
System.out.println("静态方法");
}
}
【注意事项】:
1、静态不能直接访问非静态。
原因:先人不知道后人,但是后人知道先人。 ——> 因为在内存当中是【先】有静态内容,【后】有非静态内容。
2、静态方法当中不能用this。
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象,而静态方法不属于对象。
public class Student{
private int number;
static int numberstatic; //静态变量
public void method(){
System.out.println("非静态方法");
//非静态方法访问静态变量
System.out.println(numberstatic);
//非静态方法访问非静态变量
System.out.println(number);
}
public static void methodstatic(){
System.out.println("静态方法");
//静态方法访问静态变量
System.out.println(numberstatic);
// System.out.println(number); //直接报错,静态不能访问非静态【重点】
// System.out.println(this); //直接报错,静态方法不能使用this,因为静态不属于对象
}
}
静态变量的一种用法
如下:
public class Student {
String Name;
int Age;
int id;
static String classroom = "";
static int idCloud = 0;
public Student() {
this.id = ++idCloud;
}
public Student(String name, int age) {
this.Name = name;
this.Age = age;
this.id = ++idCloud;
}
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 int getId() {
return id;
}
public static String getClassroom() {
return classroom;
}
public static void setClassroom(String classroom) {
Student.classroom = classroom;
}
}
import java.text.MessageFormat;
public class StudentDemo {
public static void main(String[] args) {
Student student01 = new Student("Wen", 10);
Student student02 = new Student("Joe", 11);
System.out.println(MessageFormat.format("姓名:{0},年龄:{1},学号:{2}",
student01.getName(),
student01.getAge(),
student01.getId()));
System.out.println(MessageFormat.format("姓名:{0},年龄:{1},学号:{2}",
student02.getName(),
student02.getAge(),
student02.getId()));
}
}
结果如下:
使用静态变量idCloud ,通过构造器使idCloud ++,然后赋值给id达到自加的效果。
静态的内存图 【重点!!!】
就拿上面的部分代码来讲:
public static void main(String[] args){
Student.classroom = "101教室";
Student student01 = new Student("Wen", 10);
Student student02 = new Student("Joe", 11);
}
可以看到静态变量不是在堆中进行赋值,而是直接在方法区的静态区中进行创建和赋值。由此看来
静态不属于任何对象,而是属于类的。
静态代码块
静态代码块的格式是:
public class 类名称{
static {
// 静态代码块的内容
}
}
特点:
1、当第一次用到本类时,静态代码块执行唯一的一次。
2、静态内容总是优先于非静态,所以静态代码块比构造方法先执
典型用途:
用来一次性地对静态成员变量进行赋值。
public class Person {
static {
System.out.println("静态代码块执行");
}
public Person(){
System.out.println("构造方法执行");
}
}
public class Man {
public static void main(String[] args) {
new Person();
System.out.println("====================");
new Person();
}
}
结果如下: