方式一,直接赋值

  1. public static Object_type var = new Object_type();

简单,便捷。常用语基本类型(long,int,short),字符串 String 等。

方式二,静态方法块

  1. public static Object_type var = null;
  2. static {
  3. var = assembly_value_method();
  4. // ...
  5. }

与方式一大同小异。
方式一与方式二,可以直接通过类模板直接访问,获取静态变量。而不需要实例化,通过实例拿取静态变量。


通过实例,反向赋值静态变量,只是模板是无法访问到实例的值。所以,以下的方式支持当前实例变来获取静态字段值。

方式三,采用 PostConstruct 初始化,当前实例来获取

  1. @PostConstruct
  2. private void init_static_val() {
  3. static_var = ...;
  4. }

方式四,实现 spring 框架的 InitializingBean 的afterPropertiesSet

就以 xxl-job 代码为小例子

  1. package com.xxl.job.admin.core.conf;
  2. import com.xxl.job.admin.core.alarm.JobAlarmer;
  3. import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
  4. import com.xxl.job.admin.dao.*;
  5. import org.springframework.beans.factory.DisposableBean;
  6. import org.springframework.beans.factory.InitializingBean;
  7. import org.springframework.beans.factory.annotation.Value;
  8. import org.springframework.mail.javamail.JavaMailSender;
  9. import org.springframework.stereotype.Component;
  10. import javax.annotation.Resource;
  11. import javax.sql.DataSource;
  12. import java.util.Arrays;
  13. /**
  14. * xxl-job config
  15. *
  16. * @author xuxueli 2017-04-28
  17. */
  18. @Component
  19. public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
  20. private static XxlJobAdminConfig adminConfig = null;
  21. public static XxlJobAdminConfig getAdminConfig() {
  22. return adminConfig;
  23. }
  24. // ---------------------- XxlJobScheduler ----------------------
  25. private XxlJobScheduler xxlJobScheduler;
  26. @Override
  27. public void afterPropertiesSet() throws Exception {
  28. adminConfig = this;
  29. xxlJobScheduler = new XxlJobScheduler();
  30. xxlJobScheduler.init();
  31. }
  32. @Override
  33. public void destroy() throws Exception {
  34. xxlJobScheduler.destroy();
  35. }
  36. // ---------------------- XxlJobScheduler ----------------------
  37. // conf
  38. @Value("${xxl.job.i18n}")
  39. private String i18n;
  40. @Value("${xxl.job.accessToken}")
  41. private String accessToken;
  42. @Value("${spring.mail.from}")
  43. private String emailFrom;
  44. @Value("${xxl.job.triggerpool.fast.max}")
  45. private int triggerPoolFastMax;
  46. @Value("${xxl.job.triggerpool.slow.max}")
  47. private int triggerPoolSlowMax;
  48. @Value("${xxl.job.logretentiondays}")
  49. private int logretentiondays;
  50. // dao, service
  51. @Resource
  52. private XxlJobLogDao xxlJobLogDao;
  53. @Resource
  54. private XxlJobInfoDao xxlJobInfoDao;
  55. @Resource
  56. private XxlJobRegistryDao xxlJobRegistryDao;
  57. @Resource
  58. private XxlJobGroupDao xxlJobGroupDao;
  59. @Resource
  60. private XxlJobLogReportDao xxlJobLogReportDao;
  61. @Resource
  62. private JavaMailSender mailSender;
  63. @Resource
  64. private DataSource dataSource;
  65. @Resource
  66. private JobAlarmer jobAlarmer;
  67. public String getI18n() {
  68. if (!Arrays.asList("zh_CN", "zh_TC", "en").contains(i18n)) {
  69. return "zh_CN";
  70. }
  71. return i18n;
  72. }
  73. public String getAccessToken() {
  74. return accessToken;
  75. }
  76. public String getEmailFrom() {
  77. return emailFrom;
  78. }
  79. public int getTriggerPoolFastMax() {
  80. if (triggerPoolFastMax < 200) {
  81. return 200;
  82. }
  83. return triggerPoolFastMax;
  84. }
  85. public int getTriggerPoolSlowMax() {
  86. if (triggerPoolSlowMax < 100) {
  87. return 100;
  88. }
  89. return triggerPoolSlowMax;
  90. }
  91. public int getLogretentiondays() {
  92. if (logretentiondays < 7) {
  93. return -1; // Limit greater than or equal to 7, otherwise close
  94. }
  95. return logretentiondays;
  96. }
  97. public XxlJobLogDao getXxlJobLogDao() {
  98. return xxlJobLogDao;
  99. }
  100. public XxlJobInfoDao getXxlJobInfoDao() {
  101. return xxlJobInfoDao;
  102. }
  103. public XxlJobRegistryDao getXxlJobRegistryDao() {
  104. return xxlJobRegistryDao;
  105. }
  106. public XxlJobGroupDao getXxlJobGroupDao() {
  107. return xxlJobGroupDao;
  108. }
  109. public XxlJobLogReportDao getXxlJobLogReportDao() {
  110. return xxlJobLogReportDao;
  111. }
  112. public JavaMailSender getMailSender() {
  113. return mailSender;
  114. }
  115. public DataSource getDataSource() {
  116. return dataSource;
  117. }
  118. public JobAlarmer getJobAlarmer() {
  119. return jobAlarmer;
  120. }
  121. }

小结

静态变量赋值,非静态方法可以访问静态变量;
静态方法,只能访问静态的变量;
类的静态变量,可以通过实例对象访问;通过实例对象初始化的静态变量值,会导致模板静态变量值改变,所以,final 来限制值的重新赋值;

  1. package com.xxl.job.xxh;
  2. import org.junit.jupiter.api.Test;
  3. import java.util.concurrent.TimeUnit;
  4. /**
  5. * <p>
  6. * xiaohui
  7. * </p>
  8. *
  9. * @author xiaohui
  10. * @email xuxiaohuimail@163.com
  11. * @since 2021/1/22
  12. */
  13. public class TestDemo {
  14. @Test
  15. public void testStaticVar() throws InterruptedException {
  16. Demo demo = new Demo();
  17. System.out.println("赋值前>>>>>>>>>>>>>");
  18. System.out.println(Demo.str);
  19. System.out.println(demo.str);
  20. System.out.println("赋值后 1 >>>>>>>>>>>>>");
  21. demo.str = "xiaohui";
  22. System.out.println(Demo.str);
  23. System.out.println(demo.str);
  24. Demo demo1 = new Demo();
  25. demo1.str = "xiaohuihui";
  26. System.out.println(demo1.str);
  27. System.out.println(Demo.str);
  28. System.out.println("原来 demo 的值");
  29. TimeUnit.SECONDS.sleep(20);
  30. System.out.println(Demo.str);
  31. System.out.println(demo.str);
  32. }
  33. @Test
  34. public void test() throws InterruptedException {
  35. TimeUnit.SECONDS.sleep(5);
  36. Demo demo = new Demo();
  37. System.out.println(Demo.str);
  38. System.out.println(demo.str);
  39. }
  40. }
  41. class Demo {
  42. public static String str = null;
  43. }

同时运行,出现下述结果:
image.png
image.png
所以,要知道 static 的变量属于模板,只有一份。


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

总而言之,static 变量,赋值后就一份,属于模板,实例化的对象共享一份。