Java中final关键字对基本类型和引用的差别

来源:互联网 发布:gps导航软件下载 编辑:程序博客网 时间:2024/06/06 11:05

package operators;import java.util.Random;class Value{    int i;    public Value(int i)    {        this.i = i;    }}public class E03_Aliasing2{    private static Random random = new Random(47);    private String id;    public E03_Aliasing2(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 VALUE_3 = new Value(33);    private final int[] a = {1, 2, 3, 4, 5, 6};    @Override    public String toString()    {        return id + ": " + "i4 = " + i4 + ",INT_5 = " + INT_5;    }    public static void main(String[] args)    {        E03_Aliasing2 fd1 = new E03_Aliasing2("fd1");        //! fd1.valueOne++; //错误,不能更改        //!fd1.VALUE_TWO++;//错误,不能更改                 fd1.v1.i++;        fd1.v2.i++;//对象本身可以改变        System.out.println("fd1.VALUE_3.i="+fd1.VALUE_3.i);        fd1.VALUE_3.i++;        System.out.println("after i+1 the value of fd1.VALUE_3.i="+fd1.VALUE_3.i);        fd1.v1 = new Value(9);//不是final,可以更改        for (int i = 0; i < fd1.a.length; i++)        {            fd1.a[i]++;//对象本身可以改变        }        //! fd1.v2 = new Value(0);//对象本身可以改变,但是引用不能改变即不能指向其他的引用        //! fd1.VAL_3 = new Value(1);        //! fd1.a = new int[3];        System.out.println(fd1);        System.out.println("创建新的FinalData");        E03_Aliasing2 fd2 = new E03_Aliasing2("fd2");        System.out.println(fd1);        System.out.println(fd2);    }}/*Output    fd1.VALUE_3.i=33    after i+1 the value of fd1.VALUE_3.i=34    fd1: i4 = 15,INT_5 = 18             创建新的FinalData    fd1: i4 = 15,INT_5 = 18    fd2: i4 = 13,INT_5 = 18    *///:~

对于基本类型添加了final后变量的值是不能修改的;对于引用类型,添加final后不能指向新的引用,但是引用的对象的可访问的数据和方法是可以修改的。

package operators;class WithFinals{    private final void f()    {    System.out.println("WithFinals.f()");    }    private void g()    {    System.out.println("WithFinals.g()");    }}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{    public final void f()    {    System.out.println("OverridingPrivate2.f()");    }    public void g()    {    System.out.println("OverridingPrivate2.g()");    }}public class E03_Aliasing2{    public static void main(String[] args)    {        OverridingPrivate2 x = new OverridingPrivate2();        x.f();        x.g();        OverridingPrivate p = x;        //! p.f(); //无法使用        //! p.g(); //无法使用        WithFinals w = x;        //! w.f(); //无法使用        //! w.g(); //无法使用    }}/* 输出    OverridingPrivate2.f()    OverridingPrivate2.g()    *///:~

 如果使用p.f()就会报错The method f() from the type OverridingPrivate is not visible。这是因为父类中使用的方法类型为private,他是无法触及而且能有效隐藏,只需将其看作是程序的代码。所以父类和子类之间的f.()和g.()方法不是复写的关系,子类中的这两个方法是生成的新的方法。

原创粉丝点击