我们经常在Java中使用static关键字,那么这么关键字究竟有哪些用途呢?我们一一道来。
1.用static修饰变量与方法
public class Main{
private static Object;
public static void fun(){
System.out.println("Test Static");
}
}
从以上代码中我们就见到static的最基本用法,也就是修饰变量和方法。那么我们肯定有疑惑,这个static关键字修饰后与普通的变量就什么不同的呢?
Static关键字代表依赖的对象是Main.class这个对象,而普通的没有static修饰的方法或者变量则依赖的是new Main()后生成的对象,所以从本质上来说两者的依赖是不一样的。
我们经常遇到的问题是在static 方法里面不能直接调用非static的变量以及方法,而在普通方法里面却可以调用static方法,为何呢?
这就跟类的加载顺序有一定的关系了,首先你在static方法里面调用非static方法/变量的话是不行的,因为有static修饰的方法会在类的初始化阶段就完成了,这个时候非static方法/变量还没有进行赋值,也就是说static修饰的方法先于非static修饰的方法完成,这样显然快的是没有办法依赖慢的喽。。但是你反过来调用确实可以的,道理我相信已经不用我在描述了。
2.用static修饰代码快
public class Main{
static{
System.out.println("static修饰代码快");
}
}
这种用法也是比较常见的用法,用static修饰的代码块只会在类进行初始化的时候调用一次!,而非static修饰的代码块则是在每次生成对象的时候都进行一次调用。原理我还是在简单说一下,因为用static修饰的代码块与Main.class所绑定,而Main.class的类信息只会加载一次的,存储在方法区里面(JDK1.8以前),所以static块也只是在加载Main.class的时候进行一次运行过程;而非static的代码块就跟随这新生成的对象来调用,new一个对象就自己调用一次。
3.用static修饰静态内部类
如果你不需要内部类对象与其外围类对象之间有联系,那你可以将内部类声明为static。这通常称为嵌套类(nested class)。Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。想要理解static应用于内部类时的含义,你就必须记住,普通的内部类对象隐含地保存了一个引用,指向创建它的外围类对象。然而,当内部类是static的时,就不是这样了。嵌套类意味着:
1. 嵌套类的对象,并不需要其外围类的对象。
2. 不能从嵌套类的对象中访问非静态的外围类对象。
如下所示代码为定义一个静态嵌套类
public class StaticTest{
private static String name = "woobo";
private String num = "X001";
static class Person{ // 静态内部类可以用public,protected,private修饰
// 静态内部类中可以定义静态或者非静态的成员
private String address = "China";
Private Static String x=“as”;
public String mail = "[email protected]";//内部类公有成员
public void display(){
//System.out.println(num);//不能直接访问外部类的非静态成员
// 静态内部类不能访问外部类的非静态成员(包括非静态变量和非静态方法)
System.out.println(name);//只能直接访问外部类的静态成员
//静态内部类只能访问外部类的静态成员(包括静态变量和静态方法)
System.out.println("Inner " + address);//访问本内部类成员。
}
}
public void printInfo(){
Person person = new Person();
// 外部类访问内部类的非静态成员:实例化内部类即可
person.display();
//System.out.println(mail);//不可访问
//System.out.println(address);//不可访问
System.out.println(person.address);//可以访问内部类的私有成员
System.out.println(Person.x);// 外部类访问内部类的静态成员:内部类.静态成员
System.out.println(person.mail);//可以访问内部类的公有成员
}
public static void main(String[] args){
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}
在静态嵌套类内部, 不能访问外部类的非静态成员, 这是由Java语法中"静态方法不能直接访问非静态成员"所限定.注意, 外部类访问内部类的的成员有些特别, 不能直接访问, 但可以通过内部类实例来访问, 这是因为静态嵌套内的所有成员和方法默认为静态的了.同时注意, 内部静态类Person只在类StaticTest 范围内可见, 若在其它类中引用或初始化, 均是错误的.
一 . 静态内部类可以有静态成员,而非静态内部类则不能有静态成员。
二 . 静态内部类的非静态成员可以访问外部类的静态变量,而不可访问外部类的非静态变量;
三 . 非静态内部类的非静态成员可以访问外部类的非静态变量。
生成一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in = new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类(正常情况下,你不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分,因为它是static 的。只是将嵌套类置于接口的命名空间内,这并不违反接口的规则)
4.用static来静态导包(JDK1.5之后)
public class Util{
public static obj=new Object();
public static void fun(){
System.out.println("测试静态导包");
}
}
------------------------------------------------------
import static Util.obj;
import static Util.fun;
public class Main{
public static void main(String[] args){
Object o=obj;
fun();
}
}
以上简单的代码中我们可以看到静态导包的好处了,就是可以省略一部分前缀,但是我们的日常使用中并不常见这种用法,主要是因为这种导包方式可能在包的数量比较多的时候会引起一定的混乱,导致代码不易阅读。
static的作用主要就是以上四种了。