方式一,直接赋值
public static Object_type var = new Object_type();
简单,便捷。常用语基本类型(long,int,short),字符串 String 等。
方式二,静态方法块
public static Object_type var = null;
static {
var = assembly_value_method();
// ...
}
与方式一大同小异。
方式一与方式二,可以直接通过类模板直接访问,获取静态变量。而不需要实例化,通过实例拿取静态变量。
通过实例,反向赋值静态变量,只是模板是无法访问到实例的值。所以,以下的方式支持当前实例变来获取静态字段值。
方式三,采用 PostConstruct 初始化,当前实例来获取
@PostConstruct
private 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
*/
@Component
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
private static XxlJobAdminConfig adminConfig = null;
public static XxlJobAdminConfig getAdminConfig() {
return adminConfig;
}
// ---------------------- XxlJobScheduler ----------------------
private XxlJobScheduler xxlJobScheduler;
@Override
public void afterPropertiesSet() throws Exception {
adminConfig = this;
xxlJobScheduler = new XxlJobScheduler();
xxlJobScheduler.init();
}
@Override
public 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
@Resource
private XxlJobLogDao xxlJobLogDao;
@Resource
private XxlJobInfoDao xxlJobInfoDao;
@Resource
private XxlJobRegistryDao xxlJobRegistryDao;
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Resource
private XxlJobLogReportDao xxlJobLogReportDao;
@Resource
private JavaMailSender mailSender;
@Resource
private DataSource dataSource;
@Resource
private 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 {
@Test
public 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);
}
@Test
public 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 变量,赋值后就一份,属于模板,实例化的对象共享一份。