Static可以用于修饰变量、方法、代码块、内部类和静态导包。
1、Static可以用于修饰变量
示例如下:
package com.cn;
public class TestStatic {
private static int a = 10;
public static void main(String[] args) {
System.out.println(TestStatic.a);
}
}
示例如下:
package com.cn;
public class TestStatic {
public static void main(String[] args) {
System.out.println(TestStatic.test());
}
public static int test(){
System.out.println("执行test方法");
return 2;
}
}
静态块如下:
package com.cn;
public class ParentClass {
static {
System.out.println("父类初始化");
}
}
有三个需要注意是事项:
①静态资源的加载顺序是严格按照静态资源的定义顺序来加载的
package com.cn;
public class TestStatic {
private static int a = test();
static {
System.out.println(a);
System.out.println("执行TestStatic类的静态块");
}
public static void main(String[] args) {
}
public static int test(){
System.out.println("执行test方法");
return 2;
}
}
输出结果:
执行test方法
2
执行TestStatic类的静态块
在类的初始化的时候,会先执行test()方法,然后是静态块
②静态代码块对于定义在它之前的静态常量可以赋值和访问,但是对于定义在它之后的静态变量,只可以赋值不可以访问。
错误如下:Cannot reference a field before it is defined
package com.cn;
public class ParentClass {
public static int b = 1;
static {
System.out.println(b);
a = 4;
System.out.println("父类初始化");
System.out.println(a);
}
public static int a = 3;
}
③静态块执行顺序:是先执行父类静态块,然后在执行子类静态块,静态块尤切只执行一次。
package com.cn;
public class ParentClass {
static {
System.out.println("父类初始化");
}
public ParentClass(){
System.out.println("父类的构造方法");
}
}
package com.cn;
public class ChildrenClass extends ParentClass{
static {
System.out.println("子类初始化");
}
public ChildrenClass(){
System.out.println("子类的构造方法");
}
}
package com.cn;
public class TestParentAndSon {
public static void main(String[] args) {
new ChildrenClass();
new ChildrenClass();
}
}
输出结果:
父类初始化
子类初始化
父类的构造方法
子类的构造方法
父类的构造方法
子类的构造方法
4、static修饰类
用static修饰的内部类就是静态内部类:
package com.cn;
public class OuterClass {
public static void look(){
System.out.println("执行OuterClass的look方法");
}
public void watch(){
System.out.println("执行OuterClass的watch方法");
}
public static class InnerClass{
public static void print(){
System.out.println("执行InnerClass的print方法");
}
public void test(){
System.out.println("执行InnerClass的test方法");
}
public static void look(){
System.out.println("执行InnerClass的look方法");
OuterClass.look();
}
}
public static void print(){
System.out.println("执行OuterClass的print方法");
}
public void test(){
System.out.println("执行OuterClass的test方法");
}
}
package com.cn;
public class TestStatic {
public static void main(String[] args) {
OuterClass.InnerClass in = new OuterClass.InnerClass();
in.test();
OuterClass.InnerClass.print();
OuterClass os = new OuterClass();
os.test();
OuterClass.print();
OuterClass.look();
}
}
输出结果:
执行InnerClass的test方法
执行InnerClass的print方法
执行OuterClass的test方法
执行OuterClass的print方法
执行OuterClass的look方法
由此得出如下结论:
静态内部类也可以拥有静态方法和非静态方法
静态内部类只可以访问外部类的静态成员和静态方法,不可以访问非静态成员和非静态方法
静态内部类访问自己内部的静态成员和静态方法时,也是通过点出来的,不过在前面需要加上外部类的名字。
例如:
OuterClass.InnerClass.print();
5、静态导包
①正常情况下,我们如果想引用Math下的静态资源,需要这样写Math.random(),
②如果我们用static这个关键字进行静态导包的话,就可以这样写random(),不必每次都添加Math类名
代码一
package com.cn;
public class TestStatic {
public static void main(String[] args) {
System.out.println(Math.random());
}
}
代码二
package com.cn;
import static java.lang.Math.*;
public class TestStatic {
public static void main(String[] args) {
System.out.println(random());
}
}
PS:代码二的话,一定要注意Math后面有一个*,不能省略
其实代码一和代码二是一样的,至于怎么使用,看各自的爱好吧