Java 常量都可以定义在哪里?

版权声明:本文为博主原创文章,同步今日头条号:Java云笔记。转载请附上博文链接: https://blog.csdn.net/weixin_44259720/article/details/88120183

哈哈,很搞笑的问题吧!可是小编在实际开发中还真的遇到了一个相关的麻烦,敦促我把这个知识点梳理一下。大神可以飘过,小白还真是要了解一下的好。

常量使用目的

1、常量提取出来有利于代码阅读,而且下次再做这种判断不用手写或复制,直接通过常量类就能得到,能够避免有的地方是username,有的地方是name来判断同一个逻辑含义相同变量问题。
不过我觉得提取出来并不会有利于代码性能提升,因为常量分配在内存的常量池中,所以内存不会出现多个相同常量字符串。总的来说提取常量主要是为了避免魔法数字和提高代码可读性。
2、常量定义在 final 的 clas 中,防止被其它类继承和实例化。定义在 interface 中性质也是一样,static final属性。但是 interface 看起来就是会被实现的。

项目场景

小编在做一个三方的业务对接时,业务方要求变更配置好的static final常量。当小编改变定义的常量值之后,遇到这样一个问题,就是将文件上传到服务器上后,发现引用这个常量的代码并没有变成新的值。

这是典型的java常量替换的应用,也是因为不够理解java常量替换的机制导致的问题。

举个小例子:

	@Test
	public class Test {
		String a = "a";
		String b = "b";
		String str1 = a + b;
		String str2 = "a" + "b";
	}

以上代码 str2 会在编译时就确定下值来,因为是两个字符串常量的连接值,字符串常量本身就是一个宏变量,而 str2 则不行,因为编译时无法确定 a 与 b 的值,如果把 a 与 b 变量定义为 final 变量,则 str1 就可以在编译时确定值。

修改办法:
其实,只需要将引用该常量新值的 java 文件重新编译成为 class 文件,并上传到服务器上即可。

原理:
当final修饰一个变量时,必须为该变量显示指定初始值,那么这个变量在编译时就可以确定下来,那么这个final变量实质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方替换成该变量的值。

而宏替换的过程是在java编译中执行的,也就是说 java 文件在编译时就直接将 final 变量替换为对应的值。当我们将final变量所在的 java 源文件编译成 class 文件后,上传到服务器上,但是引用这个 final 变量的 class 文件,依然是在引用旧的 final 变量时编译的,所以才需要将引用新的 final 变量的 class 文件上传到服务器上才可以。

常量定义场景

1、interface中定义常量:接口(Interface)的中变量默认为static final的

public interface ConstantInterface {  
    String SUNDAY = "SUNDAY";  
    String MONDAY = "MONDAY";  
    String TUESDAY = "TUESDAY";  
    String WEDNESDAY = "WEDNESDAY";  
    String THURSDAY = "THURSDAY";  
    String FRIDAY = "FRIDAY";  
    String SATURDAY = "SATURDAY";  
}

2、普通类中定义常量:在普通类中使用 static final 修饰变量

public class ConstantClassField {  
	public static final String SUNDAY = "SUNDAY";  
	public static final String MONDAY = "MONDAY";  
	public static final String TUESDAY = "TUESDAY";  
	public static final String WEDNESDAY = "WEDNESDAY";  
	public static final String THURSDAY = "THURSDAY";  
	public static final String FRIDAY = "FRIDAY";  
	public static final String SATURDAY = "SATURDAY";  
}

3、也可以使用get方法:注意,这个类里可没有set方法!!

public class ConstantClassFunction {  
	private static final String SUNDAY = "SUNDAY";  
	private static final String MONDAY = "MONDAY";  
	private static final String TUESDAY = "TUESDAY";  
	private static final String WEDNESDAY = "WEDNESDAY";  
	private static final String THURSDAY = "THURSDAY";  
	private static final String FRIDAY = "FRIDAY";  
	private static final String SATURDAY = "SATURDAY";  
	public static String getSunday() {  
		return SUNDAY;  
	}  
	public static String getMonday() {  
		return MONDAY;  
	}  
	public static String getTuesday() {  
		return TUESDAY;  
	}  
	public static String getWednesday() {  
		return WEDNESDAY;  
	}  
	public static String getThursday() {  
		return THURSDAY;  
	}  
	public static String getFirday() {  
		return FRIDAY;  
	}  
	public static String getSaturday() {  
		return SATURDAY;  
	}  
}

4、final class 定义常量:final类可以通过“类名.”的方式直接取值

public final class ConstantClassField {  
	public static final String SUNDAY = "SUNDAY";  
	public static final String MONDAY = "MONDAY";  
	public static final String TUESDAY = "TUESDAY";  
	public static final String WEDNESDAY = "WEDNESDAY";  
	public static final String THURSDAY = "THURSDAY";  
	public static final String FRIDAY = "FRIDAY";  
	public static final String SATURDAY = "SATURDAY";  
}

5、写在properties文件中:下面是读取 properties 文件的方法

public static String getProperties(String str) {
	try {
		Properties prop = new Properties();
		InputStream fis = PropertiesUtil.class.getClassLoader().getResourceAsStream("项目下properties的文件名");

		return prop.getProperty(str).trim();
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 当通过Properties读取文件后,流应当自行关闭
		prop.load(fis);
		fis.close();
	}
	return null;
}
建议
  1. 如果是一般业务场景,小编推荐使用第4种 – final class定义,和其它方法比:简洁,表面意思更清楚,不用实现接口,唯一性,通用性也更好。
  2. 如果有的变量在部署的时候可能会根据环境的不同而改变,则建议把常量写到properties文件中。
    就比如我上面的业务场景,如果之前是把常量写在properties文件中,则不会存在上传编译文件的麻烦,直接修改properties文件中的属性即可。因为properties文件中的值是重新加载的,并不适用常量替换的机制。

更多精彩,请关注我的"今日头条号":Java云笔记
随时随地,让你拥有最新,最便捷的掌上云服务

猜你喜欢

转载自blog.csdn.net/weixin_44259720/article/details/88120183