被static修饰的变量叫做静态变量,也叫做类变量。
这个变量属于类本身,而不是属于对象。
没有被static修饰的成员变量叫做实例变量,说明这个变量是属于具体对象的。
当通过类或者某个对象来修改静态变量时,所有使用到这个变量的地方,值都会变化。
public class Person { private String name; public static int age = 20; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public static int getAge() { return age; } public static void setAge(int age) { Person.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + "age='" + age + '\'' + '}'; } } public class Test { public static void main(String[] args) { Person one = new Person("张三"); Person two = new Person("李四"); System.out.println("--------使用类名调用和修改静态变量--------"); System.out.println("------修改前对象的toString------"); System.out.println(one.toString()); System.out.println(two.toString()); //权限为public时,static修饰的成员变量属于类,可以用类名调用! System.out.println("---修改前使用类名调用:"+Person.age); //可以直接使用类名调用并修改 Person.age = 21; //权限为private时需要使用get和set方法来调用和修改 System.out.println("---修改后使用类名调用:"+Person.getAge()); System.out.println("------修改后对象的toString------"); System.out.println(one.toString()); System.out.println(two.toString()); System.out.println("------------------分割线------------------"); System.out.println("--------使用对象名调用和修改静态变量--------"); //静态变量属于类,使用对象名调用修改后,所有对象和类本身使用该变量时都会变成修改后的值 System.out.println("例如使用第一个对象修改静态变量值为19"); one.age = 18; System.out.println(one.toString()); System.out.println(two.toString()); } } /* 输出结果: --------使用类名调用和修改静态变量-------- ------修改前对象的toString------ Person{name='张三'age='20'} Person{name='李四'age='20'} ---修改前使用类名调用:20 ---修改后使用类名调用:21 ------修改后对象的toString------ Person{name='张三'age='21'} Person{name='李四'age='21'} ------------------分割线------------------ --------使用对象名调用和修改静态变量-------- 例如使用第一个对象修改静态变量值为19 Person{name='张三'age='18'} Person{name='李四'age='18'} */static修饰的方法叫做静态方法,静态方法属于类。(这种写法在编译之后也会被javac(java语言编程编译器)翻译成“类名.静态方法”)。
可以通过对象名直接调用(如:对象名.静态方法名()),也可以直接通过类名称调用(如:类名称.静态方法名())(推荐使用类名调用,最终也会编译成“类名称.静态方法名()”)。
对于本类当中的静态方法可以省去类名,直接写方法名调用,在编译的时候会编译为“静态方法名()”,所以完全等效。
静态可以直接访问静态,不可以直接访问非静态(在内存中先有的静态,后有的非静态)(先人不知道后人,后人知道先人)。
静态方法中不能使用this关键字,this指的是当前对象,静态方法使用不需要创建对象。
静态方法在java web阶段写service程序时经常使用。
//本类中使用类名调用和直接调用本质都一样 public class Test{ public static void StaticMethod(){ System.out.println("静态方法执行了!!!"); } public static void main(String[] args) { //通过类名调用 Test.StaticMethod(); //本类中直接调用 StaticMethod(); } } /* 静态方法执行了!!! 静态方法执行了!!! */ //.class文件 public class Test { public Test() { } public static void StaticMethod() { System.out.println("静态方法执行了!!!"); } public static void main(String[] args) { StaticMethod(); StaticMethod(); } } //使用对象名调用和使用类名调用都会编译成"类名.静态方法名()" class Test1{ public static void main(String[] args) { Test.StaticMethod(); Test t = new Test(); t.StaticMethod(); } } //.class文件 class Test1 { Test1() { } public static void main(String[] args) { Test.StaticMethod(); Test t = new Test(); Test.StaticMethod(); } }在Java中,static一般用来修饰成员变量和成员函数,很少用来修饰类,但是普通类是不可以用static修饰的,只有内部类才可以。
static修饰内部类的意义在于,不用创建外部类实例,也可创建内部类。
public class Test{ public static class Iml{ public void TestMethod(){ System.out.println("静态内部类中的方法"); } } public static void main(String[] args) { Iml iml = new Test.Iml();//不用创建外部类实例,也可创建内部类 iml.TestMethod(); } } /* 静态内部类中的方法 */特点:当第一次使用本类时,静态代码快执行唯一一次。
执行时,静态代码块比构造方法先执行。
静态代码块典型用途:
用来一次性地对静态成员变量进行赋值。
public class Person { public Person() { System.out.println("构造方法执行了!!!"); } static { System.out.println("静态方法执行了!!!"); } } public class Test { public static void main(String[] args) { Person one = new Person(); Person two = new Person(); } } /*执行结果: 静态方法执行了!!! 构造方法执行了!!! 构造方法执行了!!! */生命周期
静态方法和静态变量一样,都属于类本身,在类装在的时候被装载到内存,不会自动销毁,会一直存在于内存中,直到JVM关闭。(但是同时也会导致占用大量资源,使用太多可能导致内存溢出)
非静态方法和变量属于实例化对象,实例化后才会分配内存,必须通过类的实例化引用,当实例对象被JVM回收之后,也跟着消失。
效率
静态方法比非静态方法使用效率高。
在内存中的位置
成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区。
如有问题,还请批评指正!!!