static关键字
1. 为什么需要static?
当在定义类的时候,类中都会有相应的属性和方法。而属性和方法都是通过创建本类对象调用的。当在调用对象的某个方法时,这个方法没有访问到对象的特有数据时,方法创建这个对象有些多余。可是不创建对象,方法又调用不了,这时就会想,那么我们能不能不创建对象,就可以调用方法呢?可以的,我们可以通过static关键字来实现。static它是静态修饰符,一般用来修饰类中的成员。
2. static特点
static主要用于修饰类中的成员。
- static修饰成员变量时:被static修饰的成员变量属于类,不属于这个类的某个对象。(也就是说,多个对象在访问或修改static修饰的成员变量时,其中一个对象将static成员变量值进行了修改,其他对象中的static成员变量值跟着改变,即多个对象共享同一个static成员变量)
代码演示:class Demo { public static int num = 100; } class Test { public static void main(String[] args) { Demo d1 = new Demo(); Demo d2 = new Demo(); d1.num = 200; System.out.println(d1.num); //结果为200 System.out.println(d2.num); //结果为200 } }
- static修饰成员方法时:如果该成员方法被子类重写之后,当进行多态调用时,调用的是父类中的静态方法!
public class StaticTestFu { public static void fu(){ System.out.println("这是父类静态方法"); } }
public class StaticTestZi extends StaticTestFu { public static void fu(){ System.out.println("这是子类重写的父类方法!"); } }
输出结果为:public class StaticTest { public static void main(String[] args) { StaticTestFu f = new StaticTestZi(); f.fu(); StaticTestZi z1 = new StaticTestZi(); z1.fu(); } }
这是父类静态方法 这是子类重写的父类方法!
- 被static修饰的成员可以并且建议通过类名直接访问。
访问静态成员的格式:
代码演示:类名.静态成员变量名 类名.静态成员方法名(参数) 对象名.静态成员变量名 ------不建议使用该方式,会出现警告 对象名.静态成员方法名(参数) ------不建议使用该方式,会出现警告
class Demo { //静态成员变量 public static int num = 100; //静态方法 public static void method(){ System.out.println("静态方法"); } } class Test { public static void main(String[] args) { System.out.println(Demo.num); Demo.method(); } }
3. static注意事项
- 静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。
class Demo { //成员变量 public int num = 100; //静态方法 public static void method(){ //this.num; 不能使用this/super。 System.out.println(this.num); } }
- 同一个类中,静态成员只能访问静态成员
class Demo { //成员变量 public int num = 100; //静态成员变量 public static int count = 200; //静态方法 public static void method(){ //System.out.println(num); 静态方法中,只能访问静态成员变量或静态成员方法 System.out.println(count); } }
- main方法为静态方法仅仅为程序执行入口,它不属于任何一个对象,可以定义在任意类中。
4. static内存分析以及总结(重点)
接下以几段代码和几个内存图来总结下static相关知识点
- 1、首先定义一个Student类:
/* * 定义Student类, * 定义对象的特有数据,和对象的共享数据 * 对象的特有数据(非静态修饰) 调用者只能是 new 对象 * 对象的共享数据(静态修饰) 调用者可以是new 对象,可以是类名 * * 被静态修饰的成员,可以被类名字直接调用 */ public class Student { String name; int age; static String schoolName; }
总结:**被static修饰的成员变量属于类所有,并且指的是改变量被所有的对象实例所共享的数据。比如学生类中的所有学生都是清华大学,学校这个属性为全体成员共享并且一模一样的。因此我们将学校定义为一个静态变量那么改变量将会跟随类加载到方法区中,不需要跟随对象进行创建存储,这样可以节约内存。**如果其中一个对象更改了静态成员变量的值,那么它会影响所有对象的值,看如下代码:
public class Test {
public static void main(String[] args) {
System.out.println(Student.schoolName);
Student s1 = new Student();
Student s2 = new Student();
s1.name = "哈哈";
s2.name = "嘻嘻";
System.out.println(s1.name);
System.out.println(s2.name);
//对象调用类的静态成员变量
s1.schoolName = "清华大学";
System.out.println(s2.schoolName);
}
}
输出结果为:
清华大学
- 2、我们重新定义下student类,来做一个总结
以下为静态内存图:/* * 静态的注意事项 * * 在静态中不能调用非静态 * * 为什么呢? 为什么静态不能调用非静态,生命周期 * 静态优先于非静态存在于内存中 * * 静态 前人 先人 非静态 后人 * * 静态不能写this,不能写super * * 问题: static 修饰到底什么时候使用,应用场景 * static 修饰成员变量,成员方法 * 成员变量加static, 根据具体事物,具体分析问题 * 定义事物的时候,多个事物之间是否有共性的数据!! * 请你将共性的数据定义为静态的成员变量 * * 成员方法加static, 跟着变量走 * 如果方法,没有调用过非静态成员,将方法定义为静态 */ public class Student { private static String name; private static int age ; private char sex; public static void function(){ System.out.println(name+age); } public static int getSum(int a,int b,int c){ return a+b+c; } public void show2(){ System.out.println(sex); } public void show(){ System.out.println(name+age); } public static void main(String[] args) { } public static void method(){ } }