0
点赞
收藏
分享

微信扫一扫

final说明

seuleyang 2022-02-03 阅读 73
java

final说明

  • 修饰类:表示类不可被继承
  • 修饰方法:表示方法不可被子类覆盖,但是可以重载
  • 修饰变量:表示变量一旦被赋值就不可以更改它的值
  1. 修饰成员变量

    • 如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值。
    • 如果final修饰的是成员变量,可以在非静态初始化块、声明该变量或者构造器中执行初始值。
  2. 修饰局部变量

    系统不会为局部变量进行初始化,局部变量必须显示初始化。因此使用final修饰局部变量时,即可在定义时指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋初始值(仅一次)

    package com.dameng;
    
    /**
     * @author Allen
     */
    public class FinalVar {
    
        /**
         * 声明时就要赋值,或者在静态代码块中赋值
         */
        private final static int A = 0;
    
    //    static {
    //        A = 1;
    //    }
    
        /**
         * 声明时、代码块或者构造函数赋值
         */
        private final int b = 0;
    
    //    {
    //        b = 1;
    //    }
    
    //    public FinalVar() {
    //        b = 2;
    //    }
    
        public static void main(String[] args) {
            // 局部变量只声明不初始化,不会报错
            final int localA;
            // 在使用之前一定要赋值
            localA = 0;
            // 报错,不允许修改
    //        localA = 1;
        }
    
    }
    
  3. 修饰基本类型数据和引用类型数据

    • 如果是基本类型的变量,则其数值一旦在初始化之后便不能更改;
    • 如果是引用类型的变量,则初始化之后不能再指向另一个对象,但引用值可以修改。
    package com.dameng;
    
    /**
     * @author Allen
     */
    public class FinalReferenceTest {
    
        public static void main(String[] args) {
            final int[] arr = {1, 2, 3, 4};
            arr[2] = 3;
            // 报错,不能对arr重新赋值
    //        arr = null;
    
            final Person person = new Person();
            person.setAge(24);
            // 报错,不能对arr重新赋值        
    //        person = null;
        }
    
        private static class Person {
            private int age;
    
            public int getAge() {
                return age;
            }
    
            public void setAge(int age) {
                this.age = age;
            }
        }
    }
    

为什么局部内部类和匿名内部类只能访问局部final变量(<=jdk7)?

匿名内部类

package com.dameng;

/**
 * 编译之后会生成两个class文件,Test.class Test$1.class
 *
 * @author Allen
 */
public class Test {

    public static void main(String[] args) {
    }

    public void test(final int b) {
        final int a = 10;
        new Thread() {
            @Override
            public void run() {
                System.out.println(a);
                System.out.println(b);
            }
        }.start();
    }

}
package com.dameng;

public class Test {
    public Test() {
    }

    public static void main(String[] args) {
    }

    public void test(final int b) {
        int a = true;
        (new Thread() {
            public void run() {
                System.out.println(10);
                System.out.println(b);
            }
        }).start();
    }
}
package com.dameng;

class Test$1 extends Thread {
    Test$1(Test this$0, int var2) {
        this.this$0 = this$0;
        this.val$b = var2;
    }

    public void run() {
        System.out.println(10);
        System.out.println(this.val$b);
    }
}

局部内部类

package com.dameng;

/**
 * 编译之后生成两个class文件,Test.class Test$1InClass.class
 *
 * @author Allen
 */
public class Test {

    private int age = 12;

    public static void main(String[] args) {

    }

    public void outPrint(final int x) {
        class InClass {
            public void inPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }

        new InClass().inPrint();
    }
}
package com.dameng;

public class Test {
    private int age = 12;

    public Test() {
    }

    public static void main(String[] args) {
    }

    public void outPrint(final int x) {
        class InClass {
            InClass() {
            }

            public void inPrint() {
                System.out.println(x);
                System.out.println(Test.this.age);
            }
        }

        (new InClass()).inPrint();
    }
}
package com.dameng;

class Test$1InClass {
    Test$1InClass(Test this$0, int var2) {
        this.this$0 = this$0;
        this.val$x = var2;
    }

    public void inPrint() {
        System.out.println(this.val$x);
        System.out.println(this.this$0.age);
    }
}

jdk8以后匿名内部类可以直接访问局部变量

匿名内部类

package com.dameng;/** * 编译之后只生成一个class文件,Test.class * * @author Allen */public class Test {    public static void main(String[] args) {    }    // final可有可无    public void test(final int b) {        // final可有可无        final int a = 10;        new Thread(() -> {            System.out.println(a);            System.out.println(b);        }).start();    }}
package com.dameng;public class Test {    public Test() {    }    public static void main(String[] args) {    }    public void test(int b) {        int a = true;        (new Thread(() -> {            System.out.println(10);            System.out.println(b);        })).start();    }}

局部内部类

package com.dameng;/** * 编译之后生成两个class文件,Test.class Test$1InClass.class * * @author Allen */public class Test {    private int age = 12;    public static void main(String[] args) {    }    // final可有可无    public void outPrint(final int x) {        class InClass {            public void inPrint() {                System.out.println(x);                System.out.println(age);            }        }        new InClass().inPrint();    }}
package com.dameng;public class Test {    private int age = 12;    public Test() {    }    public static void main(String[] args) {    }    public void outPrint(final int x) {        class InClass {            InClass() {            }            public void inPrint() {                System.out.println(x);                System.out.println(Test.this.age);            }        }        (new InClass()).inPrint();    }}
package com.dameng;class Test$1InClass {    Test$1InClass(Test this$0, int var2) {        this.this$0 = this$0;        this.val$x = var2;    }    public void inPrint() {        System.out.println(this.val$x);        System.out.println(this.this$0.age);    }}
举报

相关推荐

0 条评论