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


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.()方法不是复写的关系,子类中的这两个方法是生成的新的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值