Java Theory and Practice: Is that your final answer?

xiaoxiao2021-03-06  122

Final keywords are often misuse--declarative classes and methods, while declaring instance fields are insufficient. This month, Java practitioners Brian Goetz explore some guidelines for efficient use of Final.

Like its "post"-c in the CONST keyword, according to the context, Final represents different things. Final keywords can be applied to classes, methods, or fields. When applied to classes, it means that the class cannot regenerate a homic class. When applied to the method, it means that the method cannot be covered by the subclass. When applied to fields, it means that the value of the field must only be assigned once within each constructor and then this value will never change.

Most Java text describe the usage and consequences of using Final keywords, but rarely provide information about when to use Final and usage frequencies. According to my experience, Final is very excessively used for classes and methods (usually because developers mistakenly believe this will improve performance), and in their use of martial arts - declare example variables - insufficient use.

Why is this class final? For developers, the classes declared as Final, but not given the description of this decision, such a practice is common, especially in an open source project. After a while, especially if the original developers are no longer involved in the maintenance of the code, other developers will always ask "What kind of X is declared into final?". Usually no one knows that when someone really knows or likes to guess, the answer is almost always "because this can make it faster." The universal understanding is that the class or method declares that Final will make the compiler easier inline method to call, but this understanding is incorrect (or at least saying is greatly speech).

Final classes and methods may be very big in programming - they limit the features that you choose to reuse existing code and extension existing classes. Sometimes there is a good reason to declare the class into Final (such as forced uncapped), which will be greater than its inconvenience. Performance improvement is almost always the bad reason for the destruction of good object-oriented design principles, and when performance is small, it is really a very poor trade-off method.

Premature optimization is a bad idea for the early stage of the project, which is a bad idea in the early stage of the project, which has several reasons. First, the early stage design is not considered by loop computing performance optimization, especially when such decisions may constrain you to design using Final. Second, the performance advantages obtained by declaring the method or class into FINAL are usually zero. Moreover, the complex state-based classes declares that Final is not conducive to object-oriented design and leads to a large size and facial class because they cannot easily constitute smaller and more compact classes.

Like many of the myth of Java performance, declare the class or method into Final will bring better performance, this error concept is widely accepted but rarely. The argument is: the method or class declared that Final means that the compiler can be more actively call because it knows the version of the method to be called at runtime. But this is obviously incorrect. Just because class X is compiled into Final class y, it does not mean that the same version of the class Y will be loaded at runtime. Therefore, the compiler cannot be called safely in line with such a cross-type method, regardless of Final. Only when the method is private, the compiler can freely inline, in which case the final keyword is redundant.

On the other hand, the runtime environment and the JIT compiler have more information about what kind of information that is really loaded, which can be made more optimized than the compiler. If the runtime environment knows that the class does not load inherited Y, it can safely inline the call to the Y method, regardless of y is Final (as long as it can be built, the code compiled this JIT compiled) ). So, although Final may be useful for "dumb" runtime when do not perform any global correlation analysis, its use does not support too much compile time optimization, and intelligent JIT executes running time optimization Don't need it. It seems to have met - Recall the re-recall the register keyword Final to optimize the decision and the register keyword that is not approved in C is very similar. Let the programmer help the optimizer this wish to promote the register keyword, but in fact, it is not very useful. As we are willing to believe in other aspects, compilers in making code optimization decisions are usually excellent than people, even in the current RISC processor. In fact, most C compilers completely ignore the Register keyword. The earlier C compiler ignores it because these compilers are not optimized at all; today's compiler ignore it because the compiler does not need it to make better optimization decisions. In either case, the register keyword does not add any performance advantages, and the Final keyword applied to the Java class or method is similar. If you want to optimize your code, please insist on using the optimization of performance, such as using a valid algorithm without performing redundancy, and leaves the loop calculation to the compiler and JVM.

Using Final remoses Although performance does not declare a class or method as a good reason, sometimes there is still sufficient reasons to write a Final class. The most common thing is that Final guarantees those classes designed to not change. The invariant class is very useful for simply designing object-oriented programs - the constant object requires less defensive encoding and does not require strict synchronization. You will not build this idea in your code: Category is constant, then let some people inherit it in a variable manner. Storing the unchanged class into Final to ensure that such errors will not sneak into your program.

Final is another reason for classes or methods to prevent links between methods from being destroyed. For example, it is assumed that the implementation of a method of class X is assumed that the method M will work in some way. Declaring X or M as Final will prevent derived classes from redefining M in this manner, resulting in abnormal operation of X. Despite these internal relevance to implement X may be better, this is not always possible, and using Final can prevent such incompatible changes in the future.

If you have to use a Final class or method, please record why do you do this, when you really choose to declare a method or class, please record why this is made. Otherwise, future maintenance personnel will might be confused if there is a good reason (because there is nothing); and will be bound by your decision, but it doesn't know what the motivation you do is to get what benefits. In many cases, decisions or methods declared as FINAL have been postponed to the development process later, then you have had better information about how category interactions and how you may be inherited. You may find that you don't need to declare class as Final, or you can reconstruct classes to apply Final to smaller and simpler classes.

Final field Final fields and final classes or methods have a lot of differences, so that I think they are unfair to share the same keywords. The Final field is a read-only field, to ensure that it is built (or, when the Static Final field is initialized), only once. As discussed earlier, for Final classes and methods, you will always ask if you really need to use Final. For final fields, you will ask yourself the opposite issue - Do you really need it? You may be surprised that this answer is often "unwanted". Document Description Value Final field has several benefits. For developers who want to use or inherit your class, declare fields into Final's important document description. - Not only helps explain how this class works, but also has a compiler to strengthen your design decision Help. Unlike the final method, the Final field helps the optimizer make better optimization decisions, because if the compiler knows the value of the field does not change, it can securely cache this value in the register. The Final field also provides additional security levels by allowing the compiler to force this field for read-only.

In extreme cases, a class, its field is Final primitive or a Final reference to the constant object, then the class itself is constant - in fact this is a very convenient situation. Even if the class is not complete, it makes it greatly simplified for some of the status, you don't have to ensure that you are looking at the current value of the Final field or to ensure that no other people are changed in this part of the object state.

So why is the final field so insufficient? One reason is that it is especially true that it is especially true that it is a bit troubles that use them correctly, especially for its constructor. Because the final field must only initialize once in each constructor, if the constructor referenced by the Final object may throw an exception, the compiler may report an error, saying that the field is not initialized. The compiler is generally more intelligent, enough to find initialization in each branch of two mutual exclusive code branches (for example, if ... else block) just once, but it is usually not for Try ... catch block Will this "tolerance". For example, most Java compilers do not accept the code in Listing 1:

Listing 1. Invalid initialization of Final reference field

Public class foo {

PRIVATE FINAL THINGIE

Public foo () {

Try {

Thingie = New Thingie ();

}

Catch (ThingieConstructionexception E) {

Thingie = Thingie.getDefaultthingie ();

}

}

}

But they will accept the code in Listing 2, which is equivalent to:

Listing 2. Final reference field Effective initialization

Public class foo {

PRIVATE FINAL THINGIE

Public foo () {

Thingie temptle;

Try {

Tempthingie = New Thingie ();

}

Catch (ThingieConstructionexception E) {

Tempthingie = Thingie.getDefaultthingie ();

}

THINGIE = ​​Tempthingie;

}

}

The limitations of the final field of the Final field still have some serious restrictions. Although the array reference can be declared into Final, the elements of the array cannot be. This means that exposing the PUBLIC Final array field or by their method to return to the class to these fields (for example, the DangerousStates class shown in Listing 3) is not changeable. Similarly, although object references can be declared as a Final field, the object it is cited may still be variable. If you want to create a constant object using the Final field, you must prevent the reference to "Escape" your class for the array or variable object. Do not need to repeat this array to do this, a simple method is to convert the array into LIST, such as the Safestates class shown in Listing 3: Listing 3. Exposure array reference makes the class becomes variable

// Not Immutable - The State Array Could Be Modified by a Malicious

Caller

Public class dangerousstates {

Private final string [] statins = new string [] {"Alabama", "alaska", ...};

Public string [] getStates () {

Return stat;

}

}

// immutable - returns an unmodifiable list instead

Public class saFestates {

Private final string [] statins = new string [] {"Alabama", "alaska", ...};

Private Final List StateSASLISLIST

= new Abstract () {

Public Object Get (int N) {

Return States [N];

}

Public int size () {

Return states.length;

}

}

Public List getStates () {

Return stat;

}

}

Why don't you inherit Final to apply to an array and reference object, similar to the use of Const in C and C ? The semantics and use of Const in C are quite confusing, depending on the position that appears in the expression. Java architects managed to "rescue" from this confusion, but unfortunately they produced some new confusion in this process.

Conclusion If you want to use Final, methods, and fields, there are some basic guidelines to follow. It is important to note that do not try to use Final as a performance management tool; improve your program's performance, there is a better way to make fewer methods. Using final semantics reflecting your program: It will be read-only if these classes will be inseparable or those fields. If you choose to create a final class or method, make sure you clear why you do this - your colleague will be grateful.

转载请注明原文地址:https://www.9cbs.com/read-99439.html

New Post(0)