方式一,直接赋值
public static Object_type var = new Object_type();
简单,便捷。常用语基本类型(long,int,short),字符串 String 等。
方式二,静态方法块
public static Object_type var = null;static {var = assembly_value_method();// ...}
与方式一大同小异。
方式一与方式二,可以直接通过类模板直接访问,获取静态变量。而不需要实例化,通过实例拿取静态变量。
通过实例,反向赋值静态变量,只是模板是无法访问到实例的值。所以,以下的方式支持当前实例变来获取静态字段值。
方式三,采用 PostConstruct 初始化,当前实例来获取
@PostConstructprivate void init_static_val() {static_var = ...;}
方式四,实现 spring 框架的 InitializingBean 的afterPropertiesSet
就以 xxl-job 代码为小例子
package com.xxl.job.admin.core.conf;import com.xxl.job.admin.core.alarm.JobAlarmer;import com.xxl.job.admin.core.scheduler.XxlJobScheduler;import com.xxl.job.admin.dao.*;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.beans.factory.annotation.Value;import org.springframework.mail.javamail.JavaMailSender;import org.springframework.stereotype.Component;import javax.annotation.Resource;import javax.sql.DataSource;import java.util.Arrays;/*** xxl-job config** @author xuxueli 2017-04-28*/@Componentpublic class XxlJobAdminConfig implements InitializingBean, DisposableBean {private static XxlJobAdminConfig adminConfig = null;public static XxlJobAdminConfig getAdminConfig() {return adminConfig;}// ---------------------- XxlJobScheduler ----------------------private XxlJobScheduler xxlJobScheduler;@Overridepublic void afterPropertiesSet() throws Exception {adminConfig = this;xxlJobScheduler = new XxlJobScheduler();xxlJobScheduler.init();}@Overridepublic void destroy() throws Exception {xxlJobScheduler.destroy();}// ---------------------- XxlJobScheduler ----------------------// conf@Value("${xxl.job.i18n}")private String i18n;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${spring.mail.from}")private String emailFrom;@Value("${xxl.job.triggerpool.fast.max}")private int triggerPoolFastMax;@Value("${xxl.job.triggerpool.slow.max}")private int triggerPoolSlowMax;@Value("${xxl.job.logretentiondays}")private int logretentiondays;// dao, service@Resourceprivate XxlJobLogDao xxlJobLogDao;@Resourceprivate XxlJobInfoDao xxlJobInfoDao;@Resourceprivate XxlJobRegistryDao xxlJobRegistryDao;@Resourceprivate XxlJobGroupDao xxlJobGroupDao;@Resourceprivate XxlJobLogReportDao xxlJobLogReportDao;@Resourceprivate JavaMailSender mailSender;@Resourceprivate DataSource dataSource;@Resourceprivate JobAlarmer jobAlarmer;public String getI18n() {if (!Arrays.asList("zh_CN", "zh_TC", "en").contains(i18n)) {return "zh_CN";}return i18n;}public String getAccessToken() {return accessToken;}public String getEmailFrom() {return emailFrom;}public int getTriggerPoolFastMax() {if (triggerPoolFastMax < 200) {return 200;}return triggerPoolFastMax;}public int getTriggerPoolSlowMax() {if (triggerPoolSlowMax < 100) {return 100;}return triggerPoolSlowMax;}public int getLogretentiondays() {if (logretentiondays < 7) {return -1; // Limit greater than or equal to 7, otherwise close}return logretentiondays;}public XxlJobLogDao getXxlJobLogDao() {return xxlJobLogDao;}public XxlJobInfoDao getXxlJobInfoDao() {return xxlJobInfoDao;}public XxlJobRegistryDao getXxlJobRegistryDao() {return xxlJobRegistryDao;}public XxlJobGroupDao getXxlJobGroupDao() {return xxlJobGroupDao;}public XxlJobLogReportDao getXxlJobLogReportDao() {return xxlJobLogReportDao;}public JavaMailSender getMailSender() {return mailSender;}public DataSource getDataSource() {return dataSource;}public JobAlarmer getJobAlarmer() {return jobAlarmer;}}
小结
静态变量赋值,非静态方法可以访问静态变量;
静态方法,只能访问静态的变量;
类的静态变量,可以通过实例对象访问;通过实例对象初始化的静态变量值,会导致模板静态变量值改变,所以,final 来限制值的重新赋值;
package com.xxl.job.xxh;import org.junit.jupiter.api.Test;import java.util.concurrent.TimeUnit;/*** <p>* xiaohui* </p>** @author xiaohui* @email xuxiaohuimail@163.com* @since 2021/1/22*/public class TestDemo {@Testpublic void testStaticVar() throws InterruptedException {Demo demo = new Demo();System.out.println("赋值前>>>>>>>>>>>>>");System.out.println(Demo.str);System.out.println(demo.str);System.out.println("赋值后 1 >>>>>>>>>>>>>");demo.str = "xiaohui";System.out.println(Demo.str);System.out.println(demo.str);Demo demo1 = new Demo();demo1.str = "xiaohuihui";System.out.println(demo1.str);System.out.println(Demo.str);System.out.println("原来 demo 的值");TimeUnit.SECONDS.sleep(20);System.out.println(Demo.str);System.out.println(demo.str);}@Testpublic void test() throws InterruptedException {TimeUnit.SECONDS.sleep(5);Demo demo = new Demo();System.out.println(Demo.str);System.out.println(demo.str);}}class Demo {public static String str = null;}
同时运行,出现下述结果:

所以,要知道 static 的变量属于模板,只有一份。
方式一、方式二较为雷同,基本没有区别;
static 与 @PostConstruct 存在区别,前者属于模板,只会执行一次,后者属于实例化对象,实例化几个对象,就会执行多少次。
实现 Spring 的 InitializingBean,效果类似于 @PostConstruct 实例化对象时重新赋值。
总而言之,static 变量,赋值后就一份,属于模板,实例化的对象共享一份。
