final的使用

作者: 育王净量 | 来源:发表于2019-04-10 16:12 被阅读3次

    修饰符 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");
    
    // 在构造方法中@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", "开关打开"),
        CLOSE("close", "开关关闭");
        
        private final String code;
        private final String desc;
    }
    
    // 静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
    // 在构造代码块(优先级高于构造方法)中完成初始化
    class A{
        final int a;
        {
            a = 520;
        }
    }
    
    // 静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
    // 在静态代码块中完成初始化
    class B{
        static final String love;
        static {
            love = "you";
        }    
    }
    
    

    静态块\main()\构造块\构造方法的执行顺序

    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;
    }
    

    修饰方法中的参数,表示方法传过来的参数,在方法内不能做修改,也就是说方法里的这个参数一直指向的是你传进来的参数。当参数传进来的时候,表示初始化完成,可以防止在里面重新赋值引起程序错误。或者一些加解密场景中,只允许你使用这个值(密钥),但不允许你改变这个值。

    // 构建sftp连接,数据不允许在方法内被修改
    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循环中

    下面代码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 + " ");
            }
        }
    

    相关文章

      网友评论

        本文标题:final的使用

        本文链接:https://www.haomeiwen.com/subject/kjnniqtx.html