Java编程思想笔记

Java编程思想笔记

3.4赋值

对一个对象进行操作时,我们真正操作的是对对象的引用。所以倘若“将一个对象赋值给另一个对象”,实际上是将“引用”从一个地方复制到另一个地方。这意味着假若对对象使用c=d,那么c和d都指向原本只有d指向的那个对象。
下面是书上的例子:

package wj.three;

public class Assignment {

    class Tank{
        int level;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Assignment assignment = new Assignment();
        Tank t1 = new Tank();
        Tank t2 = new Tank();
        t1.level = 9;
        t2.level = 47;
        System.out.println("1: t1.level:" + t1.level + 
                ", t2.level:" + t2.level);
        t1 = t2;
        System.out.println("2: t2.level:" + t1.level + 
                ", t2.level:" + t2.level);

        t1.level = 27;
        System.out.println("3: t1.level:" + t1.level + 
                ", t2.level:" + t2.level);
    }

}

但是会报错: No enclosing instance of type Assignment is accessible. Must qualify the allocation with an enclosing instance of type Assignment (e.g. x.new A() where x is an instance of Assignment).

查了网上一些资料,暂时发现3种解决方案:
1、错误翻译成中文是(有道翻译):无法访问类型分配的封闭实例。必须以指定的类型分配(例如x)来限定分配。(比如x.new A(),x是赋值的一个实例)。
所以先定义一个外部类的对象,然后用该对象创建该内部类的实例。代码如下:

        Assignment assignment = new Assignment();
        Tank t1 = assignment.new Tank();
        Tank t2 = assignment.new Tank();

2、因为内部类是动态的,而主函数是 static。在Java中,类中的静态方法不能直接调用动态方法。将内部类修改为静态类,才能在静态方法中调用该静态类的成员变量与成员方法。代码如下:

    public static class Tank{
        int level;
    }

3、将该内部类在Assignment类外部定义。代码如下:

package wj.three;

class Tank{
    int level;
}

public class Assignment {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Tank t1 = new Tank();
        Tank t2 = new Tank();
        t1.level = 9;
        t2.level = 47;
        System.out.println("1: t1.level:" + t1.level + 
                ", t2.level:" + t2.level);
        t1 = t2;
        System.out.println("2: t2.level:" + t1.level + 
                ", t2.level:" + t2.level);

        t1.level = 27;
        System.out.println("3: t1.level:" + t1.level + 
                ", t2.level:" + t2.level);
    }

}

运行结果为:
1: t1.level:9, t2.level:47
2: t2.level:47, t2.level:47
3: t1.level:27, t2.level:27

发现第3行输出结果,t2的值随着修改t1发生了改变,这是由于t1和t2包含的是相同的引用,它们指向相同的对象,原本t1包含的对象的引用是指向一个值为9的对象。在对t1赋值的时候,这个引用被覆盖,也就是丢失了;而那个不在被引用的对象会有“垃圾回收器”自动清理。
这种特殊的现象通常称做“别名现象”,在这个例子中,如果想避免别名问题应该这样写:

t1.level = t2.level;

这样便可以保持两个对象批次独立,而不是将t1和t2绑定到相同的对象。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值