JAVA中关于局部内部类的问题
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是由JVM中java的数据内存结构决定的。
一个类在jvm中会被实例化为一个类实例,new关键字产生的对象实例,通过对象实例头部信息中的指针指向类实例。
由此,可以体会出,在java运行内存结构中,一个类的每一个部分(构造方法、属性、注解、普通方法)都(可能)存在一个对应实例。比如方法会对应有一个方法实例。在方法中定义的局部类,只能在方法内部访问,因为这个局部类是属于方法实例的,而非类实例。
局部类可以访问局部常量,这个关系到局部常量是在什么时候被初始化的(类加载相关知识和编译优化)。如果这个局部变量在加载过程中(加载、验证、准备解析、初始化)被初始化,那么局部类中访问常量的地方会指向局部常量。
以上答案是个人的理解,经过简化,也许会和《深入理解JVM》的部分论述细节有出入,有兴趣的话,题主还是自己去阅读一下原书更好些。
我觉得此时此刻,将局部内部类 Apple,写在 SellOutClas 类的成员方法之内,就表明局部内部类 Apple是SellOutClas 类一部分,不是这样吗?
回复
将 Apple 写在内部,当然就可以当成 SellOutClas 类的一部分来看待,好处就是 可以直接读取 SellOutClas 类的私有属性。不过 Apple 作为一个类,也可以将其定义在 SellOutClas 类的定义之外。
"在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的定义之外。
参考:
Java内部类详解