Java static关键字与静态块

xiaoxiao2021-02-28  85

一.static修饰符

static 修饰符能够与属性、方法和内部类一起使用,表示是“静态”的。

类中的静态变量和静态方法能够与“类名”一起使用,不需要创建一个类的对象来访问该类的静态成员。所以static修饰的变量又称作“类变量”。这与实例变量不同。实例变量总是用对象来访问,因为它们的值在对象和对象之间有所不同。

下列示例展示了如何访问一个类的静态变量: class StaticModifier { static int i = 10; int j; StaticModifier() { j = 20; } } public class Test { public static void main(String args[]) { System.out.println(“类变量 i=” + StaticModifier.i); StaticModifier s = new StaticModifier(); System.out.println(“实例变量 j=” + s.j); } } 上述程序的输出是: 类变量 i=10 实例变量 j=20

二.static属性的内存分配

在上面的例子中,无需创建类的对象即可访问静态变量 i。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,因此它能够用类名进行访问。也就是说:一个类中,一个 static 变量只会有一个内存空间,虽然有多个类实例,但这些类实例中的这个static 变量会共享同一个内存空间。示例如下: public class Test { public static void main(String[] args) { UserModel um1 = new UserModel(); um.userName = “张三”; um.country = “china”; UserModel um2 = new UserModel(); um2.userName = “李四”; um2.country = “中国”; System.out.println(“um1.userName==” + um1.userName +” um1.country==” + um1.country ); System.out.println(“um2.userName==” + um2.userName +” um2.country==” + um2.country ); } } class UserModel { public static String country public String userName; } 运行结果: um1.userName==张三 um1.country==中国 um2.userName==李四 um2.country==中国

为什么会是一样的值呢?就是因为多个UserModel 实例中的静态变量country 是共享同一内存空间,um1.country 和 um2.country 其实指向的都是同一个内存空间,所以就得到上面的结果了。

在对象um2创建前的运行后内存分配示意图如下:

在对象um2创建后的运行后内存分配示意图如下:

要想看看是不是 static 导致这样的结果,你可以尝试去掉country前面的 static,然后再试一试,看看结果,应该如下: um1.userName==张三 um1.country==china um2.userName==李四 um2.country==中国 还有一点也很重要:static 的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static 变量,它都会被初始化。

小结一下:类变量(class variables)用关键字 static 修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。

三.static的基本规则

有关静态变量或方法的一些要点如下:

一个类的静态方法只能访问静态属性; 一个类的静态方法不能够直接调用非静态方法; 如访问控制权限允许,static 属性和方法可以使用对象名加“.”方式调用;当然也可以使用实例加“.”方式调用; 静态方法中不存在当前对象,因而不能使用“this”,当然也不能使用”super”; 静态方法不能被非静态方法覆盖; 构造方法不允许声明为 static 的; 局部变量不能使用static修饰。

static 方法可以用类名来访问,如: public class GeneralFunction { public static int addUp(int x, int y) { return x + y; } } public class UseGeneral { public void method() { int a = 9; int b = 10; int c = GeneralFunction.addUp(a, b); System.out.println(“addUp() gives ” + c); } } 因为 static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值。结果是,static方法不能访问与它本身的参数以及 static 变量之外的任何变量,访问非静态变量的尝试会引起编译错误。

注:非静态变量只限于实例,并只能通过实例引用被访问。

四.静态初始器——静态块

静态初始器(Static Initializer)是一个存在与类中方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次。静态初始器的功能是:往往用来初始化静态的类属性。

示例: class Count { public static int counter; static {// 只运行一次 counter = 123; System.out.println(“Now in static block.”); } public void test() { System.out.println(“test method==” + counter); } } public class Test { public static void main(String args[]) { System.out.println(“counter=” + Count.counter); new Count().test(); } } 运行结果是: Now in static block. counter=123 test method==123

五.静态import

当我们要获取一个随机数时,写法是: public class Test { public static void main(String[] args) { double randomNum = Math.random(); System.out.println(“the randomNum==” + randomNum); } } 从 JDK5.0 开始可以写为: import static java.lang.Math.random; public class Test { public static void main(String[] args) { double randomNum = random(); System.out.println(“the randomNum==” + randomNum); } } 静态引用使我们可以象调用本地方法一样调用一个引入的方法,当我们需要引入同一个类的多个方法时,只需写为“import static java.lang.Math.*”即可。这样的引用方式对于枚举也同样有效。

转载请注明原文地址: https://www.6miu.com/read-23268.html

最新回复(0)