Java Interface 是常量存放的最佳地点吗?

由于Java编程 interface中声明的字段在编译时会自动加上static final的修饰符,即声明为常量。因而interface通常是存放常量的最佳地点。然而在Java编程的实际实际运用时却会产生一部份疑难问题。

疑难问题的起因有两个,NO·1,是咱们所应用的常量并否则一成不变的,而是相对于变量别赋值改变。例如咱们在唯一工程初期定义常量∏=3.14,而由于计算精度的升高咱们估计会重新定义∏=3.14159,此时整个项目对此常量的引用都因该做出改变。第二,Java编程是动态语句语言。与c++之类的静态语句语言不相同,Java编程对一部份字段的引用能够在运行期动态停止,这种灵活性是Java编程那样的动态语句语言的一大优势。也就使得咱们在Java编程工程中有时部份内容的改变不用重新编译整个项目,而只需编译改变的部份重新正式发布就能够改变整个实际运用。

讲了这么多,你还不明白我要说什么吗?好,咱们来看唯一简单的例子:

有唯一interface A,唯一class B,代码Code如下:


//file A.Java编程
public interface A{
String name = "bright";
}

//file B.Java编程
public class B{
public static void main(String[] args){
System.out.println("Class A's name = " + A.name);
}
}




够简单吧,好,编译A.Java编程和B.Java编程。

运行,输入Java编程 B,显然结果如下:


Class A's name = bright




咱们目前改正A.Java编程如下:


//file A.Java编程
public interface A{
String name = "bright sea";
}




编译A.Java编程后重新运行B class,输入Java编程 B,留意:结果如下


Class A's name = bright




为啥否则"Class A's name = bright sea"?让咱们应用jdk帮助的反编译道具Java编程p反编译B.class看个究竟,输入:Java编程p -c B ,结果如下:


Compiled from B.Java编程
public class B extends Java编程.lang.Object {
public B();
public static void main(Java编程.lang.String[]);
}

Method B()
0 aload_0
1 invokespecial #1
4 return

Method void main(Java编程.lang.String[])
0 getstatic #2
3 ldc #3
5 invokevirtual #4
8 return




留意到标号3的代码Code了吗?由于引用了唯一static final 的字段,编译器已经将interface A中name的内容编译进了class B中,而否则对interface A中的name的引用。因此除非咱们重新编译class B,interface A中name除了的变化无法在class B中反映。假如那样去做那么Java编程的动态优势就消失殆尽。

解决方案,有两种解决窍门。

NO·1种窍门是不再应用常量,将所需字段放入class中声明,并去掉final修饰符。但这种窍门存在一定的风险,由于不再是常量着因而在操作系统运行时有估计被更多有联系类改正其值而除了错误,也就违背了咱们设置它为常量的初衷,因而不推荐应用。

第二种窍门,将常量放入class中声明,应用class窍门来得到此常量的值。为了保持对此常量引用的简单性,咱们能够应用唯一静态窍门。咱们将A.Java编程和B.Java编程改正如下:


//file A.Java编程
public class A{
private static final String name = "bright";
public static String getName(){
return name;
}
}

//file B.Java编程
public class B{
public static void main(String[] args){
System.out.println("Class A's name = " + A.getName());
}
}




同样咱们编译A.Java编程和B.Java编程。运行class B,输入Java编程 B,显然结果如下:

Class A's name = bright

目前咱们改正A.Java编程如下:


//file A.Java编程
public class A{
private static final String name = "bright";
public static String getName(){
return name;
}
}




咱们再次编译A.Java编程后重新运行B class,输入Java编程 B:结果如下


Class A's name = bright sea




终于得到了咱们想要的结果,咱们能够再次反编译B.class看看class B的改变,输入:

Java编程p -c B,结果如下:


Compiled from B.Java编程
public class B extends Java编程.lang.Object {
public B();
public static void main(Java编程.lang.String[]);
}

Method B()
0 aload_0
1 invokespecial #1
4 return

Method void main(Java编程.lang.String[])
0 getstatic #2
3 new #3
6 dup
7 invokespecial #4
10 ldc #5
12 invokevirtual #6
15 invokestatic #7
18 invokevirtual #6
21 invokevirtual #8
24 invokevirtual #9
27 return

留意标号10至15行的代码Code,class B中已经变为对A class的getName()窍门的引用,当常量name的值改变时咱们只需对class A中的常量做改正并重新编译,无需编译整个项目工程咱们就能改变整个实际运用对此常量的引用,即保持了Java编程动态优势又保持了咱们应用常量的初衷,因而窍门二是唯一最佳解决方案。
详细内容:
http://www-900.ibm.com/developerWorks/cn/Java编程/l-Java编程-interface/index.shtml?n-j-04281

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值