static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
class Person{ private Date birthDate; public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { Date startDate = Date.valueOf("1946-1-1"); Date endDate = Date.valueOf("1964-12-31"); return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; } }
isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:
class Person{ private Date birthDate; private static Date startDate,endDate; static{ startDate = Date.valueOf("1946-1-1"); endDate = Date.valueOf("1964-12-31"); } public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; } }因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
二.static关键字的误区 1.static关键字会改变类中成员的访问权限吗? Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。看下面的例子就明白了: package cn.bzu.look.dao; public class StaticTest { public static void main(String[] args) { //这一句会报错The field Person.name is not visible System.out.println(new Person().name); System.out.println(new Person().age); } } class Person{ private String name="哈哈"; public int age =10; } 2.能通过this访问静态成员变量吗? 虽然对于静态方法来说没有this,那么在非静态方法中能够通过this访问静态成员变量吗?先看下面的一个例子,这段代码输出的结果是什么? public class StaticTest { static int value=33; public static void main(String[] args) { new StaticTest().print(); } public void print() { int value=3; System.out.println(this.value); } }返回的结果是33
这里面主要考察队this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
3.static能作用于局部变量么? **在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。** 4、static,与final的对比static关键字修饰变量时,会使该变量在类加载时就会被初始化,不会因为对象的创建再次被加载,当变量被static 修饰时就代表该变量只会被初始化一次
package cn.bzu.look.dao; public class StaticTest { public static double i = Math.random(); public final double j = Math.random(); public static void main(String[] args) { StaticTest staticTest1 = new StaticTest(); StaticTest staticTest2 = new StaticTest(); System.out.println(staticTest1.i==staticTest2.i); System.out.println(staticTest1.j==staticTest2.j); } }输出的结果是
功能:
修饰属性.方法,块,内部类
1、静态元素在;类加载的时候就被初始化,创建的很早,那时还没有创建对象
2、静态元素存储在静态元素区中,每一个类都有自己的一个单独的区域,与别的类不冲突
3、静态元素区不能被GC管理,可以简单的认为静态元素常驻内存
4、静态元素只加载一次,供全部的类对象和类本身共享
5、可以理解为静态元素与对象没有关系,它属于类
6、由于静态元素在加载的时候可能还没有创建对象,我们可以直接通过类名直接静态元素
7、静态元素可以直接访问静态元素。
8、非静态元素可以直接方法静态元素,但是静态元素不能直接方法非静态元素
9、静态元素中不可以使用this,super关键字