package cn.bzu.look.dao;
public class MyObject {
//非静态变量
private String str1 ="property";
//静态变量
private static String str2 ="staticProperty";
public MyObject() {
}
//非静态方法
public void print1() {
System.out.println(str1);
System.out.println(str2);
print2();
}
//静态方法
public static void print2() {
//这一句报错,报错信息是Cannot make a static reference to the non-static field str1
System.out.println(str1);
System.out.println(str2);
/*
* 调用非静态的方法会报错,
* Cannot make a static reference to the non-static method print1() from the type MyObject
*/
print1();
}
}
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代码块中进行。
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;
}
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。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
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关键字