所有分类
  • 所有分类
  • 未分类

Java–static–用法/使用位置/实例

简介

本文用示例介绍Java中的static的用法。

使用位置包括:修饰成员属性,修饰成员方法,修饰代码块,修饰内部类,静态导包。

用法1:修饰成员属性

说明

给属性加了static关键字之后,对象就不再拥有该属性了,该属性会由类去管理,即多个对象只对应一个属性。

使用场景

一般用于定义一些常量。

示例:

package com.example.a;

class Test{
    public static String NAME = "Tony";
}

public class Demo {
    public static void main(String[] args) {
        System.out.println(Test.NAME);
    }
}

执行结果

Tony

用法2:修饰成员方法

说明

方法本来就是存放在类的定义当中的。static修饰成员方法的作用是可以使用”类名.方法名”的方式操作方法,避免了先要new出对象的繁琐和资源消耗。

示例:

package com.example.a;

class Test{
    public static void sayHello(String name) {
        System.out.println("Hello," + name);
    }
}

public class Demo {
    public static void main(String[] args) {
        Test.sayHello("Tony");
    }
}

结果

Hello,Tony

用法3:修饰代码块

static { }就是静态块,当类加载器载入类的时候,这一部分代码被执行,常用于对静态变量进行初始化工作。当其他代码用到这个类,类加载器才会将它载入。

代码只能执行一次,不能再调用。在静态块中,可以访问静态变量,调用静态方法。

如果去掉static,{ }中的代码则会在创建类对象的时候才执行,(相当于把这部分代码复制到各个构造函数中),这样可以实现块中的内容在多个构造函数中的复用。

package com.example.a;

class Test{
    static {
        System.out.println("This is static Block");
    }

    {
        System.out.println("This is Block");
    }

    public Test(){
        System.out.println("This is Test()");
    }

    public Test(String string){
        System.out.println("This is Test(String string)");
    }
}

public class Demo {
    public static void main(String[] args) {
        System.out.println("------------------------");
        Test test1 = new Test();
        System.out.println("------------------------");
        Test test2 = new Test("Hello");
    }
}

执行结果

------------------------
This is static Block
This is Block
This is Test()
------------------------
This is Block
This is Test(String string)

用法4:修饰内部类

static不能修饰普通类,但可以修饰内部类。原因如下:

static修饰的东西被我们成为类成员,它会随着类的加载而加载,比如:静态代码块,静态成员,静态方法(这里只是加载,并没有调用)等等。若把一个Class文件中的外部类设为static,那目的何在呢?难道让这个类随着应用的启动而加载吗?如果我在这次使用过程中根本没有使用过这个类,那么是不是就会浪费内存。这样来说设计不合理,总而言之,设计不合理的地方,Java是不会让它存在的。

为什么内部类可以使用static修饰呢,因为内部类算是类的成员了,如果我们没有使用静态来修饰,那么我们在创建内部类的时候就需要先有一个外部类的对象,如果我们一直在使用内部类,那么内存中就会一直存在外部类的引用,而我们有时候只需要使用内部类,不需要外部类,那么还是会浪费内存,甚至会造成内存溢出。使用static修饰内部类之后,内部类在创建对象时就不需要有外部类对象的引用了。

实例:

单例模式的静态内部类写法(Java设计模式系列–单例模式(6种写法) – 自学精灵

public class Singleton {
    private static class SingletonHolder {
	    private static final Singleton INSTANCE = new Singleton();
    }

    private Singleton (){}

    public static final Singleton getInstance() {
	    return SingletonHolder.INSTANCE;
    }
}

public class Demo{

    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println(singleton);
    }

}

用法5:静态导包

导入时,使用static关键字,而且在引入类的最后还加上了“.*”,它的作用就是将PrintHelper类中的所有类方法直接导入。不同于非static导入,采用static导入包后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法了,直接可以采用”方法名”去调用类方法,就好像是该类自己的方法一样使用即可。

/* PrintHelper.java文件 */
package com.dotgua.study;
 
public class PrintHelper {
    public static void print(Object o){
        System.out.println(o);
    }
}
import static com.dotgua.study.PrintHelper.*;

public class Demo{
    public static void main( String[] args )
    {
        print("Hello World!");
    }
}

static加载顺序

首先思考,下边程序是否能编译通过?若可以编译通过,那么执行结果是什么?

package com.example.a;

class User{
    private static String name;

    public void setName(String name) {
        this.name = name;
    }

    public static String getName() {
        return User.name;
    }
}

public class Demo {
    public static void main(String[] args) {
        new User().setName("Tony");
        System.out.println(User.getName());
    }
}

 结果

Tony

从上述结果可见,实例对象可以访问访问类变量。

如果将setName改为static类型,则无法编译通过。static里边不能有this,这与类加载流程有关,见:JVM原理–类加载过程(有实例) – 自学精灵

2

评论5

请先

  1. 用法三里面的执行结果是不是有一点问题。应该先输出this is static Block,然后再输出分割线
    凛晨 2024-02-21 0
    • 我试了一下,是正确的呀。在调用new Test()之前不会走初始化流程,所以不会输出Test类里边的东西的。
      自学精灵 2024-02-21 0
      • 我的问题,我把它们都放到一个类里面了。
        凛晨 2024-02-21 0
  2. 最后的链接不可访问 404
    Thinking_Fission 2023-10-09 0
显示验证码
没有账号?注册  忘记密码?

社交账号快速登录