JAVA中关于局部内部类的问题

发布于 2022-01-01 17:17:49 字数 1943 浏览 877 评论 4

package mingrikeji;

public class SellOutClass {
    private String name; // 私有成员变量

    public SellOutClass() {// 构造方法
        name = "苹果";
    }

    public void sell(int price) {
        class Apple { // 局部内部类
            int innerPrice;

            public Apple(int price) {// 构造方法
                innerPrice = price;
            }

            public void price() {// 方法
                System.out.println("现在开始销售" + name);// name为外部类的成员变量
                System.out.println("单价为:" + innerPrice + "元");// innerPrice为局部内部类的成员变量
            }
        }
        Apple apple = new Apple(price);// 实例化Apple类的对象
        apple.price();// 调用局部内部类的方法
    }

    public static void main(String[] args) {
        SellOutClass sample = new SellOutClass();// 实例化SellOutClass类的对象
        sample.sell(100);// 调用SellOutClass类的sell()方法
    }

}

 

1.连sell方法都是SellOutClass的一部分,为什么说局部内部类Apple并非SellOutClass的一部分
2.“该内部类可以访问当前代码块的常量”是什么意思?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

德意的啸 2022-01-07 23:12:50

这是由JVM中java的数据内存结构决定的。

一个类在jvm中会被实例化为一个类实例,new关键字产生的对象实例,通过对象实例头部信息中的指针指向类实例。

由此,可以体会出,在java运行内存结构中,一个类的每一个部分(构造方法、属性、注解、普通方法)都(可能)存在一个对应实例。比如方法会对应有一个方法实例。在方法中定义的局部类,只能在方法内部访问,因为这个局部类是属于方法实例的,而非类实例。

局部类可以访问局部常量,这个关系到局部常量是在什么时候被初始化的(类加载相关知识和编译优化)。如果这个局部变量在加载过程中(加载、验证、准备解析、初始化)被初始化,那么局部类中访问常量的地方会指向局部常量。

 

以上答案是个人的理解,经过简化,也许会和《深入理解JVM》的部分论述细节有出入,有兴趣的话,题主还是自己去阅读一下原书更好些。

眼泪淡了忧伤 2022-01-07 03:07:37

我觉得此时此刻,将局部内部类 Apple,写在 SellOutClas 类的成员方法之内,就表明局部内部类 Apple是SellOutClas 类一部分,不是这样吗?

成熟的代价 2022-01-06 20:56:43

回复
将 Apple 写在内部,当然就可以当成 SellOutClas 类的一部分来看待,好处就是 可以直接读取 SellOutClas 类的私有属性。不过 Apple 作为一个类,也可以将其定义在 SellOutClas 类的定义之外。

凌乱心跳 2022-01-06 08:46:25

    "在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类"。

    楼主所示的内部类 Apple 的定义,写在了 定义公共类 SellOutClass 的成员方法的代码块之中,即写在公共类 SellOutClass 的成员方法 public void sell(int price) 定义的里面。
这样安排的优点(便宜)是:
    使得 内部类 Apple 的成员方法 public void price() 得以直接访问当前代码块,即 类 SellOutClass 的成员变量/常量,或调用其成员方法, 无论这些 变量/常量/方法 是共有的,受保护的,还是私有的。就楼主所示的案例而言,就是指 得以访问(取值/赋值) 类 SellOutClass 的成员字符串常量 name。
    就类 SellOutClass 的所谓的 私有成员变量 name 而言,其实是一个一旦生成了实体/对象,就默认为"苹果"的字符串常量,  因为它是一个 外界无法再改变的字符串 "苹果"。于是,“该内部类可以访问当前代码块的常量” 可以解读为:该内部类 Apple 可以访问当前代码块的常量 name。这就是将代码写成内部类的优点。

    尽管按楼主的案例,将 局部内部类 Apple,写在 SellOutClas 类的成员方法之内, 但 它 (类 Apple) 并不是 SellOutClass 类的一部分。它完全可以写在 公共类 SellOutClass的定义之外。当然,这样一来,就没有任何内部类的便宜可占了。 由于 类 Apple 不再是 类 SellOutClass 的内部类,类 Apple 的成员方法 price()  里的代码,就不能直接访问 类 SellOutClass 的私有属性 name。因此,
1. 必须为 类 SellOutClas 增添一个公共的方法 getName(),
2. 必须在类 Apple 的成员方法 public void price() 的定义里,先创建一个  类 SellOutClass 的实体 sc,然后,以 sc 作为引用来调用 SellOutClas 类的成员方法 getName()方法,以便获取 name 的值。 
总而言之,"局部内部类Apple并非SellOutClass的一部分", 它完全可以写在 公共类 SellOutClass的定义之外。

public class SellOutClass {
     private final String name; // 私有成员变量

    public SellOutClass() {// 构造方法
        name = "苹果"; //默认常量值"苹果",一旦生成实体,外界就无法再改变的字符串常量 "苹果"。
     }

    public void sell(int price) {
         
        Apple apple = new Apple(price);// 实例化Apple类的对象
        apple.price();// 调用 外部类 Apple 的 方法 price()
    }
    
    public String getName(){
    	return name;
    }

    public static void main(String[] args) {
         SellOutClass sample = new SellOutClass();// 实例化SellOutClass类的对象
         sample.sell(100);// 调用SellOutClass类的sell()方法
    }

}

class Apple { // 外部 类 Apple
            int innerPrice;

            public Apple(int price) {// 构造方法
                innerPrice = price;
             }

            public void price() {// 方法
            SellOutClass sc = new SellOutClass();	//创建一个  类 SellOutClass 的实体 sc
            System.out.println("现在开始销售" + sc.getName());//  借助 方法 getName()获取 name的值。
            System.out.println("单价为:" + innerPrice + "元");// innerPrice 是类 Apple 的属性
                
            }
}

参考:
Java内部类详解
 

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文