java中有一個關鍵字-
final
. 它可以應用於類別、方法、變數(包括方法參數)。 對於一個類,這意味著該類不能有子類,即 禁止繼承。這在創建(不可變)物件時非常有用immutable
,例如聲明String
為final
.
public final class String{
}
class SubString extends String{ //Compilation error
}
還應該注意的是,修飾符不能應用於抽象類別(帶有關鍵字abstract
),final
因為 這些都是互相排斥的概念。對於一個方法final
意味著它不能在子類別中被重寫。當我們希望原始實作不被覆蓋時,這很有用。
public class SuperClass{
public final void printReport(){
System.out.println("Report");
}
}
class SubClass extends SuperClass{
public void printReport(){ //Compilation error
System.out.println("MyReport");
}
}
對於原始類型變量,這意味著一旦分配,值就不能更改。對於引用變量,這意味著一旦分配了對象,對該對象的引用就無法更改。這很重要!連結無法更改,但物件的狀態可以更改。隨著 java 8 出現了這個概念 - effectively final
. 它僅適用於變數(包括方法參數)。重點是,儘管明顯缺少關鍵字final
,變數的值在初始化後並沒有改變。換句話說,您可以用一個單字取代此類變量,final
而不會出現編譯錯誤。變數可以在本機類別 ( )、匿名類別 ( )、流 (Stream API) effectively final
中使用。Local Inner Classes
Anonymous Inner Classes
public void someMethod(){
// In the example below, both a and b are effectively final, since the values are set once:
int a = 1;
int b;
if (a == 2) b = 3;
else b = 4;
// c is NOT effectively final because value changes
int c = 10;
c++;
Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Compilation error
}
現在我們來進行一下採訪。畢竟,參加 JavaRush 課程的目標是成為 Java 開發人員並獲得有趣且高薪的工作。 那麼,讓我們開始吧。
-
當數組被宣告時你能說什麼
final
? -
已知類別
String
是immutable
,類別被聲明final
,字串的值儲存在數組中char
,數組用關鍵字標記final
。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
是否可以替換物件的值String
(而不更改物件的參考)?這些都是真實的面試問題。實踐表明,許多人的回答都是錯誤的。了解關鍵字 的使用final
,特別是對於引用變量,非常重要。當您思考的時候,我們先暫時離開 JavaRush 團隊。請在文字編輯器中新增一個區塊,該區塊可讓您隱藏內容,並在您按一下它時顯示該內容。答案:
-
因為 數組是一個對象,這
final
意味著給一個對象分配一個引用後,就不能再改變它了,但是可以改變該對象的狀態。final int[] array = {1,2,3,4,5}; array[0] = 9; //ok, because change the contents of the array - {9,2,3,4,5} array = new int[5]; //compile error
-
是的你可以。關鍵是要理解帶刺詞與物體的用法
final
。使用ReflectionAPI來替換值。
import java.lang.reflect.Field;
class B {
public static void main(String[] args) throws Exception {
String value = "Old value";
System.out.println(value);
//Get the value field in the String class
Field field = value.getClass().getDeclaredField("value");
//Let's change it
field.setAccessible(true);
//Set new value
field.set(value, "JavaRush".toCharArray());
System.out.println(value);
/* Вывод:
* Old value
* JavaRush
*/
}
}
請注意,如果我們嘗試以這種方式更改基本類型的最終變量,則不會有任何效果。我建議您說服自己這一點:例如,創建一個帶有final int
字段的 Java 類,並嘗試透過 Reflection API 更改其值。祝你們好運!
GO TO FULL VERSION