1.static关键字用途
static方法内部不可以调用非静态方法,反过来却可以,还可以通过类本身来调用static方法。
static 可以修饰类的成员方法、类的成员变量、还可以编写代码块。
1.1.编写代码块
Static修饰的代码块在实例化之前,就会执行,具体例子如下:
public classTestStatic {
static {
System.out.println("Hello Static!");
}
public TestStatic() {
System.out.println("Hello TestStatic!");
}
public static void main(String[] args) {
TestStatictestStatic = new TestStatic();
}
}
执行结果如下:
HelloStatic!
Hello TestStatic!
以上结果证明:
被static关键字修饰的代码块在类加载的时候就会执行。因为被static修饰的变量或方法不需要实例化就可以通过类名来访问,只要类被加载就可以调用,同理static修饰的代码块,只要类加载了,就会执行,不会等着实例化。
例子如下:
public class TestStatic {
static {
System.out.println("Hello Static!");
}
public TestStatic() {
System.out.println("Hello TestStatic!");
}
public static void main(String[] args) {
// TestStatictestStatic = new TestStatic();
}
}
结果为:Hello Static!
1.2.类成员变量
Static变量也成为静态变量,他与非静态变量的区别是:静态变量被所有的对象共享,在内存中只有一个副本,只在类初次加载的时候被初始化。而非静态变量时对象所拥有的,在创建对象的时候被初始化,可以存在多个副本,各个对象拥有的副本互不影响。
例子如下:
public classTestStatic {
static {
System.out.println("Hello Static!");
}
public TestStatic() {
System.out.println("Hello TestStatic!");
}
public static String test = "test1";
}
public classTestStaticTwo {
public static void main(String[] args) {
System.out.println(TestStatic.test);
}
}
TestStaticTwo运行的结果为:
Hello Static!
test1
1.3.static与This
能通过this关键字调用静态变量
public classTestStaticTwo {
static String value = "TEST";
public static void main(String[] args) {
newTestStaticTwo().printValue();
}
private void printValue() {
Stringvalue = "TEST!";
System.out.println(this.value);
}
}
运行输出结果:TEST
原因是:this代表当前对象,上例通过newTestStaticTwo()方法调用printValue方法,其中new TestStaticTwo()代表当前对象。Static变量是被所有对象共享的,而printValue中的value变量是局部变量,不能被当前对象调用,所以输出结果为TEST;
2.static其他应用
2.1. static变量与final变量一起应用
Final关键字的作用是保证被修饰的变量不变,static的作用是成员变量只存在一个副本,两个结合起来就能保证被修饰的变量只存在一个不变的副本。
代码如下:
报错:The final fieldTestStaticTwo.test cannot be assigned
其中finalstatic 与static final 起到的作用一致
2.2.static 修饰的内部类
定义一个内部类:
public class InnerClass {
private String name;
private String sex;
private Student student;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Student getStudent() {
return student;
}
public void setStudent(Studentstudent) {
this.student = student;
}
public class Student {
private String stuId;
private BigDecimal grade;
public String getStuId() {
return stuId;
}
public void setStuId(String stuId){
this.stuId = stuId;
}
public BigDecimal getGrade() {
return grade;
}
public void setGrade(BigDecimalgrade) {
this.grade = grade;
}
@Override
public String toString() {
StringBuilderbuilder = newStringBuilder();
builder.append("Student [stuId=");
builder.append(stuId);
builder.append(", grade=");
builder.append(grade);
builder.append("]");
return builder.toString();
}
}
}
当仅仅需要实例化student时,代码调用:
public class TestInnerClass {
public staticvoidmain(String[] args) {
Student stu = new Student();
}
}
这样会报错:The value of the local variable stu is not used
- No enclosing instance oftype InnerClass is accessible. Must qualify the allocation with an enclosinginstance of type InnerClass (e.g. x.new A() where x is an instance of
InnerClass).
修改后:
InnerClass inner = new InnerClass();
Studentstu = inner.new Student();
因为Student是innerClass中的内部类,内部类是依赖于外部类存在的,所以在使用非静态内部类时,要求先实例化外部类才可以使用内部类。
当在Student之前加上static修饰时,就可以直接实例化student,因为static变量可以在没有创建对象的情况下来进行调用
参考:
http://www.cnblogs.com/dolphin0520/p/3799052.html