您好,登錄后才能下訂單哦!
Java中方法用final修飾參數的作用
在方法參數前面加final關鍵字就是為了防止數據在方法體重被修改。
主要分為兩種情況:第一,用final修飾基本數據類型;第二,用final修飾引用數據類型。
第一種情況,修飾基本數據類型,這時參數的值在方法體內是不能被修改的,即不能被重新賦值。否則編譯就不通過。
第二種情況,修飾引用類型。這時參數變量所引用的對象是不能被改變的。但是對于引用數據類型,如果修改其屬性的話是完全可以的。
所以,final這個關鍵字,想用的話就用基本數據類型,還是很有作用的。
final變量:
對于基本類型使用final:它就是一個常量,數值恒定不變
對于對象引用使用final:使得引用恒定不變,一旦引用被初始化指向一個對象,就無法再把 它改為指向另一個對象。然而,對象自身卻是可以被修改的,java并沒有提供使任何對象恒定不變的途徑。這一限制同樣也使用數組,它也是對象。
例子:
class Value{ int i; public Value(int i){ this.i = i; } } public class FinalData { private static Random random = new Random(47); private String id; public FinalData(String id){ this.id = id; } private final int valueOne = 9; private static final int VALUE_TWO = 99; public static final int VALUE_THREE = 39; private final int i4 = random.nextInt(20); static final int INT_5 = random.nextInt(20); private Value v1 = new Value(11); private final Value v2 = new Value(22); private static final Value VAL_3 = new Value(33); private final int[] a = {1, 2, 3, 4, 5, 6}; public String toString(){ return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5; } public static void main(String[] args) { FinalData fd1 = new FinalData("fd1"); //! fd1.valueOne++; // 因為valueOne是基本類型常量,其數值恒定不變 fd1.v2.i++; //final修飾的對象的內容可以改變 fd1.v1 = new Value(9); for(int i = 0; i < fd1.a.length; i++) fd1.a[i]++; //! fd1.v2 = new Value(0); // 因為v2是final修飾的引用類型,其引用不能被修改指向另一個對象 //! fd1.VAL_3 = new Value(1); // 表示占據一段不能改變的內存空間 //! fd1.a = new int[3]; // final修飾的數組 System.out.println(fd1); System.out.println("Creating new FinalData"); FinalData fd2 = new FinalData("fd2"); System.out.println(fd1); System.out.println(fd2); } } /*output: fd1: i4 = 15, INT_5 = 18 Creating new FinalData fd1: i4 = 15, INT_5 = 18 fd2: i4 = 13, INT_5 = 18 */
分析:
對于fd1,fd2兩個對象,其中i4是唯一的,即每個對象都有一個i4,但INT_5被聲明為static,即是類共享的,fd1和fd2共享INT_5,在裝載時已經被初始化,而不是每次創建新對象時初始化(例如i4);但它同時被設置成final,所以它的引用是不可改變的,即不能被修改指向另一個對象。
空白final:
被聲明為final但又沒有給定初值。必須在域的定義或者每個構造器中使用表達式對final進行賦值,這正是final域在使用前總是初始化的原因。
final參數:
這意味著你無法在方法中更改參數引用,使其指向另一個參數,但可以修改final對象所指向的內容
例子:
class Gizmo{ int i = 0; public void spin(){} } public class FinalArguments { void with(final Gizmo g){ //! g = new Gizmo(); // 無法修改final修飾的引用,使它指向另一個對象 g.i++; // 但可以修改final對象所指向的內容 } void without(Gizmo g){ g = new Gizmo(); g.spin(); } // int g(final int i){ // //! i++; //因為參數i是常量值 // } int g(final int i){ return i + 1; } public static void main(String[] args) { FinalArguments bf = new FinalArguments(); bf.without(null); bf.with(null); } }
分析:
參數被聲明為final,若是基本參數,那它就是一個常量,不能被修改;若是一個引用變量,那么它就不能被修改指向另一個對象,但可以修改該引用所指對象的內容。
fianl方法:
使用原因:
類中所有的private方法都隱式地指定為final,由于無法取用private方法,所以也就無法覆蓋它。可以對private方法添加final修飾詞,但這并不會給該方法帶來任何額外的意義。
例子:
class WithFinals{ private final void f(){ System.out.println("WithFinals.f()"); } private void g(){ System.out.println("OverridingPrivate.f()"); } } class OverridingPrivate extends WithFinals{ private final void f(){ System.out.println("OverridingPrivate.f()"); } private void g(){ System.out.println("OverridingPrivate.g()"); } } class OverridingPrivate2 extends OverridingPrivate{ /* * 當使用Override注解強制使f()方法覆蓋父類的f()方法時,會報錯 * 因為它不知道父類是否有該方法,對于g()方法來說,它只是生成了一個新的方法, * 并沒有覆蓋掉父類中的g()方法。 */ //@Override public final void f(){ System.out.println("OverridingPrivate2.f()"); } public void g(){ System.out.println("OverridingPrivate2.g()"); } } public class FinalOverridingIllusion{ public static void main(String[] args) { OverridingPrivate2 op2 = new OverridingPrivate2(); op2.f(); op2.g(); // 可以向上轉型 OverridingPrivate op = op2; //! op.f(); // 父類中final方法對子類來說是不可見的 //! op.g(); WithFinals wf = op2; // wf.f(); // wf.g(); } } /*output: OverridingPrivate2.f() OverridingPrivate2.g() */
分析:
覆蓋何時發生:
1,子類中出現與父類完全一致的方法
2. 子類可以通過向上轉型為父類,并調用父類中的那個方法
若父類中某個方法被聲明為final或者private,那么這個方法對子類來說是不可見的,就算在子類中創建了與父類一模一樣的方法,這也是一個新的方法,而不是從父類中覆蓋的方法。
final類:
即該類不能被繼承,不管是你還是別人,也就是這個類不需要做任何變動,也不需要任何子類,例如String類。
例子:
class SmallBrain{} final class Dinosaur{ int i = 7; int j = 1; SmallBrain x = new SmallBrain(); void f(){} } // error: The type Further cannot subclass the final class Dinosaur // Dinosaur類不能有子類 // class Further extends Dinosaur{} public class Jurassic { public static void main(String[] args) { Dinosaur n = new Dinosaur(); n.f(); n.i = 40; n.j++; } }
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。