在 Java 中,为什么需要创建内部类对象之前需要先创建外部类对象

文章目录

  我们知道,在 Java 中,创建一个内部类对象之前,需要它的一个外部类对象。这是因为内部类可能使用外部类的数据。

  在内部类中,有一个隐式字段指向其外部类的对象,而这个字段是内部类在被创建时,隐式初始化的。具体来说,内部类所有的构造器都自动被插入了一个匿名隐式形参,这个匿名隐式形参就是外部类对象引用,它被作为所有构造器的第一个形参,且自动用于完成对外部类对象引用的初始化。

  当使用外部类对象来创建内部类对象时,这个隐式形参不需要额外作为实参提供给内部构造器。创建内部类对象的外部类对象将自动被用于初始化上述隐式字段。

  当使用反射来调用内部类的构造器时,需要把外部类对象作为构造器的第一个实参传入。示例代码如下。

package demo;

public class Outer {
    private String outerData;

    public Outer(String outerData) {
        this.outerData = outerData;
    }

    public String getOuterData() {
        return outerData;
    }

    public void setOuterData(String outerData) {
        this.outerData = outerData;
    }

    public class Inner {
        private String innerData;

        public Inner(String innerData) {
            this.innerData = innerData;
        }

        public String getInnerData() {
            return innerData;
        }

        public void setInnerData(String innerData) {
            this.innerData = innerData;
        }

        public String getOuterData() {
            return outerData;
        }

        public void setOuterData(String externalData) {
            outerData = externalData;
        }

        public String getTravelInfo() {
            return innerData + " is on the " + outerData + " now.";
        }
    }
}

package demo;

import java.lang.reflect.InvocationTargetException;

public class Other {
    public static void main(String[] args)
            throws NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, InstantiationException {
        /*****************************************************/
        /**
         * 使用外部类对象创建内部类对象
         */
        Outer train = new Outer("train");
        Outer.Inner alice = train.new Inner("Alice");
        Outer.Inner bob = train.new Inner("Bob");
        System.out.println(alice.getTravelInfo()); // Alice is on the train now.
        System.out.println(bob.getTravelInfo()); // Bob is on the train now.

        /**
         * 外部类对象 sea 与两个内部类对象相绑定。
         * 例如,当外部类对象 sea 的信息改变时,
         * 这两个内部类对象引用的关于外部类信息也会改变
         */
        train.setOuterData("China Harmony");
        System.out.println(alice.getTravelInfo()); // Alice is on the China Harmony now.
        System.out.println(bob.getTravelInfo()); // Bob is on the China Harmony now.
        /*---------------------------------------------------*/

        /*****************************************************/
        /**
         * 借助反射来动态绑定内部类与外部类
         */
        Outer outer = Outer.class.getConstructor(String.class)
                .newInstance("Hello, world.");
        Outer.Inner inner = Outer.Inner.class
                .getConstructor(Outer.class, String.class)
                .newInstance(outer, "Hello, my world.");

        System.out.println(inner.getOuterData()); // Hello, world.
        System.out.println(inner.getInnerData()); // Hello, my world.
        /*---------------------------------------------------*/
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值