Java代码
1. //代码1:内部类实例
2. class Outer{
3. ........
4. class Inner{
5. ......
6. }
7. }
//代码1:内部类实例
class Outer{
........
class Inner{
......
}
}
所有的内部类代码都有这样两个特点:
(1) 在外部类的作用范围内可以任意创建内部类对象,即使内部类是私有的。(内部类对外部类可见)
Java代码
1. //代码2:内部类对外部类可见
2. class Outer{
3. //创建私有内部类对象
4. public Inner in=new Inner();
5. //私有内部类
6. private class Inner{
7. ...
8. }
9. }
//代码2:内部类对外部类可见
class Outer{
//创建私有内部类对象
public Inner in=new Inner();
//私有内部类
private class Inner{
...
}
}
(2) 在内部类中可以访问其外部类的所有成员。(外部类对内部类可见)
Java代码
1. //代码3:外部类对内部类可见
2. class Outer{
3. //外部类私有数据域
4. private int data=0;
5. //内部类
6. class Inner{
7. void print(){
8. //内部类访问外部私有数据域
9. System.out.println(data);
10. }
11. }
12. }
//代码3:外部类对内部类可见
class Outer{
//外部类私有数据域
private int data=0;
//内部类
class Inner{
void print(){
//内部类访问外部私有数据域
System.out.println(data);
}
}
}
这里我们好好探究一下Java内部类的"内部"
其实,内部类是Java编译器一手操办的。虚拟机并不知道内部类与常规类有什么不同。 编译器是如何瞒住虚拟机的呢?
对内部类进行编译后发现有两个class文件:Outer.class 和Outer$Inner.class 。这说明内部类Inner仍然被编译成一个独立的类(Outer$Inner.class),而不是Outer类的某一个域。 虚拟机运行的时候,也是把Inner作为一种常规类来处理的。
但问题来了,即然是两个常规类,为什么他们之间可以互相具有私有权限那(最开始提到的两个内部类特点)?这就要问问编译器到底把这两个类编译成什么东西了。
我们利用reflect反射机制来探查了一下内部类编译后的情况(关于探查类内部机制的代码提供在下面的附件里Reflect.java)。
1、编译代码2生成 Outer$Inner.class 文件后使用 ReflectUtil.reflect("Outer$Inner") 对内部类Inner进行反射。运行结果 发现了三个隐含的成分:
Html代码
1. class Outer$Inner
2. {
3. Outer$Inner(Outer,Outer$Inner); //包可见构造器
4. private Outer$Inner(Outer); //私有构造器将设置this$0域
5. final Outer this$0; //外部类实例域this$0
6. }
class Outer$Inner
{
Outer$Inner(Outer,Outer$Inner); //包可见构造器
private Outer$Inner(Outer); //私有构造器将设置this$0域
final Outer this$0; //外部类实例域this$0
}
好了,现在我们可以解释上面的第一个内部类特点了: 为什么外部类可以创建内部类的对象?
首先编译器将外、内部类编译后放在同一个包中。
然后在内部类中附加一个包可见构造器。
这样, 虚拟机运行Outer类中Inner in=new Inner(); 实际上调用的是包可见构造: new Outer$Inner(this,null)。
因此即使是private内部类,也会通过隐含的包可见构造器成功的获得私有内部类的构造权限。
2、编译代码3生成 Outer.class文件,然后使用 ReflectUtil.reflect("Outer") 对外部类Outer进行反射 。 运行结果 发现一个隐含成分如下:
Html代码
1. class Outer
2. {
3. static int access$0(Outer); //静态方法,返回值是外部类私有域 data 的值。
4. }
class Outer
{
static int access$0(Outer); //静态方法,返回值是外部类私有域 data 的值。
}
现在可以解释第二个特点了:为什么内部类可以引用外部类的私有域?
原因的关键就在编译器在外围类中添加了静态方法access$0。 它将返回值作为参数传递给他的对象域data。这样内部类Inner中的打印语句:
System.out.println(data);
实际上运行的时候调用的是:
S ystem.out.println(access$0(Outer));
总结一下编译器对内部类做的手脚吧:
(1) 在内部类中偷偷摸摸的创建了包可见构造器,从而使外部类获得了创建权限。
(2) 在外部类中偷偷摸摸的创建了访问私有变量的静态方法,从而 使 内部类获得了访问权限。
分享到:
相关推荐
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
Windows之父Jim Allchin曾经说过不要满足于只知道How-to、小技巧之类的知识,而是应该深入底层了解其内部原理。只有了解了这些安全特性的内在原理,才能真正了解Windows Vista是怎样精心替我们解决安全问题的,才能...
网路岗8代网络监控软件8.01.65破解补丁300用户,无限时间企业版 内部全网首发。网路岗最新破解补丁,网路岗软件自己去官网下载,本补丁下好后查看里面的安装说明。本补丁无毒无后门,纯手工绿色编写。讫今为止,8.01...
“文档/视图”结构是MFC中结构最为复杂,体系最为庞大,而又最富有特色的部分,其中涉及到应用、文档模板、文档、视图、SDI窗口、MDI框架窗口、MDI子窗口等多种不同的类,如果不了解这些类及其盘根错节的内部联系的...
新一代站群是一款技术领先的站群管理软件,不需要依赖CMS即可建站的首创批量建站软件,具有一键更新广告、一键链轮、内置文章原创内核等功能,能让你在短时间内...让你领略站群最前沿的技术 适合个人创业、企业公司、
文件内部包含2023年全国大学生物联网设计竞赛(华为杯)命题,内容详细,如果大家有想法做物联网相关比赛的话,强烈建议下载观看,都是各大公司出题,在观看中大家可以领略 IoT 华为云开发平台、5G 网络、5G 通信...
在这里,你不仅能深入学习jQuery的各种特性和技巧,还能领略到jQuery的内部工作机制和插件体系结构以及背后的各种策略和理论,学会怎样与其他工具和框架交互。有了jQuery和这《jQuery实战》,你不需要再费心劳力地...
《ace技术内幕:深入解析ace架构设计与实现原理》从构架模式、编程示例和源代码3个维度系统地对经典网络框架ace(adaptivemunicationenvironment)的架构设计和...,帮助框架设计者领略软件框架设计的普适原则和思想...
您将领略到如何通过集成的解决方案,实现从会计处理到财务分析、从预算编制到资金流管理的无缝对接。此外,它还重点展示了智能技术如人工智能、机器学习和预测分析如何赋能财务决策,提升企业的财务透明度和运营效率...
自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略ReactJs的风采吧~~ 文章有点长,耐心读完,你会有很大收获哦~ 一、ReactJS简介 React 起源于 Facebook ...
那么本篇博客中就要使用LLDB来调试从AppStore下载安装的App,并且结合着Hopper来分析第三方App内部的结构。LLDB与Hopper的结合,会让你看到不一样的东西,本篇博客就会和你一起领略LLDB与Hopper的魅力。 一、SSH的...
日前国外媒体曝光了诺基亚这款WP8旗舰级机型的内部构造,没错,我们熟悉的拆解手机,一起来领略下诺基亚Lumia 920的“内心世界”和她的完美部件吧: 据介绍,这些拆解图片可能来自诺基亚服务维修部门,图片...
你都将在 GoF 的设计模式里领略到它们变幻无穷的魔力。 GoF 的设计模式表面上好象也是一种具体的"技术",而且新的设计模式不断在出现,设计模式自有其自己的发展轨道,而这 些好象和 J2EE .Net 等技术也无关! ...