Is Java Interface a constant location?
Bright (bightsee@21cn.com)
Since the fields declared in Java Interface automatically add Static Final modifiers, that is, the declaration is constant. Thus Interface is usually the best place to store constants. However, there will be some problems when Java's practical application. There are two causes for problems, first, it is not a constant that we use is not a constant, but it cannot be assigned relative to variables. For example, we define constants π = 3.14 in an engineering, and we may redefine π = 3.14159 due to the improvement of calculation accuracy, and the entire project should be changed. Second, Java is a dynamic language. Unlike the static language such as C , Java's reference to some fields can be done in operation. This flexibility is a major advantage in the dynamic language of Java. That is also made in the Java project, there is no change in the content of some content, and the entire application can be changed only by recompiling the entire project, and only the part of the translation change can change the entire application. Telling so much, don't you know what I am going to say? Ok, let's look at a simple example: there is an interface A, a class b, the code is as follows:
// 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);
}
}
Simple enough, good, compile A. Java and B.java. Run, enter Java B, obviously the result is as follows:
Class a's name = BRIGHT
We now modify A.java as follows:
// file a.java
Public interface a {
String name = "Bright SEA";
}
After compiling A.java, re-run B Class, enter Java B, pay attention: the result is as follows
Class a's name = BRIGHT
Why isn't it "class a's name = bright sea"? Let's use the anti-compilation tool of JDK Java to compile B.Class to see, enter: javap -c b, the result is as follows:
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
Do you notice the code of the label 3? Since a Static Final field is referenced, the compiler has compiled the contents of the Name in Interface A into the Class B instead of reference to Name in Interface A. Therefore, unless we recompiled Class B, the change in Name in Interface A cannot be reflected in Class B. If you do this, the dynamic advantage of Java disappears. Solutions, there are two solutions. The first method is no longer used constant, put the desired field in the Class declaration and remove the final modifier. However, this method has a certain risk, because it is no longer a constant to modify its value by other classes when the system is running, it is contrary to our original intention to set it for constants, so it is not recommended. The second method, puts the constant into the Class declaration, using the Class method to obtain the value of this constant. In order to maintain the simplicity of this constant reference, we can use a static method. We will modify A. Java and B.java as follows: // File A.java
Public class a {
Private static final string name = "badht";
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 ());
}
}
Also we compile A. Java and B.java. Run Class B, enter Java B, obvious results as follows: Class a's name = Bright Now we modify A. Java as follows:
// file a.java
Public class a {
Private static final string name = "badht";
Public static string getname () {
Return Name;
}
}
After compiling A.java, we re-run B Class, enter Java B: The result is as follows
Class a's name = Bright SEA
Finally got the results we want, we can re-compile B.Class to see the change of Class B, enter: javap -c b, the results are as follows:
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