final的使用

修飾符 final 其本意為,adj.最終的;決定性的;不可更改的。可以用于修飾類、方法、變量。


final-used.png

修飾變量來表示常量

When a variable is declared with final keyword, its value can’t be modified, essentially, a constant. This also means that you must initialize a final variable.It is good practice to represent final variables in all uppercase, using underscore to separate words.

// 必須在定義的時候完成初始化
public static final HttpMethod METHOD_GET = new HttpMethod("GET");
public static final HttpMethod METHOD_POST = new HttpMethod("POST");

// 在構(gòu)造方法中@RequiredArgsConstructor完成初始化
// If you have more than one constructor in your class ,
// then it must be initialized in all of them, otherwise compile time error will be thrown.
@Getter
@RequiredArgsConstructor
public enum SwitchEnum {
    
    OPEN("open", "開關(guān)打開"),
    CLOSE("close", "開關(guān)關(guān)閉");
    
    private final String code;
    private final String desc;
}

// 靜態(tài)代碼塊其實就是給類初始化的,而構(gòu)造代碼塊是給對象初始化的。
// 在構(gòu)造代碼塊(優(yōu)先級高于構(gòu)造方法)中完成初始化
class A{
    final int a;
    {
        a = 520;
    }
}

// 靜態(tài)代碼塊其實就是給類初始化的,而構(gòu)造代碼塊是給對象初始化的。
// 在靜態(tài)代碼塊中完成初始化
class B{
    static final String love;
    static {
        love = "you";
    }    
}

靜態(tài)塊\main()\構(gòu)造塊\構(gòu)造方法的執(zhí)行順序

If the final variable is a reference, this means that the variable cannot be re-bound to reference another object, but internal state of the object pointed by that reference variable can be changed i.e. you can add or remove elements from final array or final collection. It is good practice to represent final variables in all uppercase, using underscore to separate words.
A final variable cannot be re-assign. But in case of a reference final variable, internal state of the object pointed by that reference variable can be changed. Note that this is not re-assigning. This property of final is called non-transitivity.

class Gfg 
{ 
    public static void main(String[] args)  
    { 
        // a final reference variable sb 
        final StringBuilder sb = new StringBuilder("Geeks"); 
          
        System.out.println(sb); 
          
        // changing internal state of object 
        // reference by final reference variable sb 
        sb.append("ForGeeks"); 
          
        System.out.println(sb); 
    }     
} 

修飾類表示不能繼承

When a class is declared with final keyword, it is called a final class. A final class cannot be extended(inherited).

// 不讓繼承的目的是不可擴展
public final class Integer extends Number implements Comparable<Integer>{
    ...
} 

// 不讓繼承的目的是不允許修改
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    ...
}

修飾方法表示不能重寫

When a method is declared with final keyword, it is called a final method. A final method cannot be @overridden. The Object class does this—a number of its methods are final.We must declare methods with final keyword for which we required to follow the same implementation throughout all the derived classes.

public class Object {
    public final native void notify();
    public final native void notifyAll();
    public final native void wait(long timeout) throws InterruptedException;
}

修飾方法中的參數(shù),表示方法傳過來的參數(shù),在方法內(nèi)不能做修改,也就是說方法里的這個參數(shù)一直指向的是你傳進(jìn)來的參數(shù)。當(dāng)參數(shù)傳進(jìn)來的時候,表示初始化完成,可以防止在里面重新賦值引起程序錯誤。或者一些加解密場景中,只允許你使用這個值(密鑰),但不允許你改變這個值。

// 構(gòu)建sftp連接,數(shù)據(jù)不允許在方法內(nèi)被修改
public static ChannelSftp getSftp(final String host,
                                         final int port,
                                         final String username,
                                         final String password,
                                         final String requestId,
                                         final String thirdAppCode) throws Exception {
        String key = getKey(host, port, username, password);
        
        Callable<Channel> callable = () -> {
            Session sshSession = getSession(host, port, username, password, thirdAppCode);
            Channel channelExist = sshSession.openChannel("sftp");
            channelExist.connect(CHANNEL_TIMEOUT);
            return channelExist;
        };
        
        FutureTask<Channel> futureTask = new FutureTask<>(callable);
        FutureTask<Channel> channelFutureTask = SFTP_CHANNEL_POOL.putIfAbsent(key, futureTask);
        channelFutureTask = futureTask;
        channelFutureTask.run();
        Channel channel = channelFutureTask.get();
        return (ChannelSftp) channel;
    }

特別說明final使用在for循環(huán)中

下面代碼run fine,實際上在每次迭代中,i都會重新被申明。

public void test() {
        int arr[] = {1, 2, 3};
        
        // final with for-each statement 
        // legal statement 
        for (final int i : arr) {
            System.out.print(i + " ");
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容