内部类是一种编译器现象,与虚拟机无关。编译器将会把内部类翻译成用美元符号$分隔外部类名与内部类名的常规类文件,而虚拟机对此一无所知。编译器为了引用外部类,生成了一个附加的实例域this$0

为什么要用内部类?

  • 内部类可以访问所在类域中的数据(包括私有);
  • 内部类可以在同一包中被隐藏;
  • 匿名内部类在实现回调时非常方便;

特殊语法

  • OuterClass.this表示外部类对象引用,比如Employee.this.id;
  • OuterObject.new InnerClass()显式调用内部对象的构造函数,例如this.new Payroll(10000);
  • OuterClass.InnerClass其它类访问内部类;
  • OuterClass$InnerClass编译器翻译成JVM能够识别的类,内部类对JVM是透明的.

内部类表现形式

  • 简单内部类
  • 局部的内部类
  • 匿名内部类
  • 静态内部类

简单内部类

每个内部类对象都有一个指向外部对象的隐式引用outer;每次外部类对象初始化一个内部类对象时都会把自己的this引用传给内部类对象的隐式的构造函数,以下是模拟的过程:

public class Outer{
//隐式会把this传给内部类对象的构造函数,实际这个过程看不到也不用去写.
public void function(){
Inner inner = new Inner(this);
....
} public class Inner{
//内部类有个隐式的构造函数生成外部类对象的引用,实际这个过程看不到也不用去显示调用
private Outer outer;
public Inner(Outer outer){
this.outer = outer;
}
}
}

实例如下

public class Employee {

    // 实例化对象时,在调用构造函数之前前初始化字段;
private int id; // 实例化对象时初始化为0
private String name; // 实例化对象时初始化为null
public Employee(int id, String name) {
this.id = id;
this.name = name; } public void start(){
//局部的内部类
class Computer{
private int seq;
public Computer(int seq){
this.seq = seq; public void run(){
System.out.println(seq + " computer is run");
}
} Computer c = new Computer(2015);
c.run();
} //简单内部类
public class Payroll {
private int pay;
//以下是模拟生成外部类对象的引用
// private Employee outer;
// public Payroll(Employee e) {
// this.outer = e;
// } public Payroll(int pay) {
this.pay = pay;
} // 每个内部类对象都有一个指向外部对象的隐式引用outer,可以把id和name想象成outer.id和outer.name
public void printPay() {
//if (id == 1) {
if(Employee.this.id ==1){
System.out.println("name is " + name);
System.out.println("pay is: " + pay);
System.out.println("----------------------------");
} else {
System.out.println("you can not print pay");
}
}
} public void printPayroll() {
//Payroll p = new Payroll(10000);
Payroll p = this.new Payroll(10000);
p.printPay();
} public static void main(String[] args) {
Employee e1 = new Employee(1, "a");
Employee e2 = new Employee(2, "b");
e1.printPayroll();
e2.printPayroll();
e1.start();
}
}

局部的内部类

在外部类方法中定义的内部类称为局部内部类,局部内部类不能用修饰符(public or private)定义.只能访问局部方法作用域的final变量.

    public void start(){
final int num = 2015;
class Computer{
private int seq;
public Computer(int seq){
this.seq = seq;
} public void run(){
System.out.println("seq is: " + seq + ", num is: " + num);
}
} Computer c = new Computer(2015);
c.run();
}

匿名内部类

语法如下,SuperType可是接口也可以是类.匿名内部类不能有构造函数.匿名内部类隐式地继承了一个父类或者实现了一个接口。

new SuperType(construction parameters)

{

inner class method and data

}

或者是

new InterfaceType()

{

inner class method and data

}

实例

new Thread() {
//匿名内部类
@Override
public void run() {
System.out.println("----------------------------");
System.out.println("this is a anonymous class run");
}
}.start();

静态内部类

静态内部类与其它内部类相似,不同之处在于静态内部类没有指向外部类的引用.当不需要访问外部对象时,可以考虑使用静态内部类.被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。 注意,声明在接口中的内部类自动成为public和static。

实例

public class StaticInner {
private static int a = 4; // 静态内部类
public static class Inner {
public void test() {
// 静态内部类可以访问外部类的静态成员
// 并且它只能访问静态的
System.out.println(a);
}
} public static void main(String[] args) {
StaticInner.Inner inner = new StaticInner.Inner();
inner.test();
}
}

Java内部类总结的更多相关文章

  1. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  2. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  3. 黑马----JAVA内部类

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...

  4. java 内部类 *** 最爱那水货

    注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...

  5. java内部类和匿名内部类

    内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...

  6. Java内部类小程序(成员内部类,静态内部类,匿名内部类)

    /** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...

  7. [转] Java内部类详解

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  8. java内部类的作用分析

    提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...

  9. 9)Java内部类(Inner Class)

      内部类:不可以有静态数据,静态方法或者又一个静态内部类      内部类的优点:隐藏类的细节,内部类可以声明为私有.内部类可以访问外部类的对象(包括private) 静态内部类:可以有静态数据,静 ...

  10. JAVA内部类(转)

    源出处:JAVA内部类 在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部.内部类作为其外部类的一个成员,与其他成员一样, ...

随机推荐

  1. Java学习——static关键字

    静态:static用法:是一个修饰符,用于修饰成员(成员变量或函数).当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用.类名.静态成员 ststic特点:1, 随着类 ...

  2. Android系统休眠对程序的影响以及处理

    Android系统在用户长时间不操作时,为了节省资源,系统会选择休眠.在休眠过程中自定义的Timer.Handler.Thread.Service等都会暂停.而有时候这种机制会影响到我们程序的正常运行 ...

  3. C#中equals方法和==的区别

    Msdn中对equals方法的解释是:确定指定的对象是否等于当前对象. Equals方法是比较对象的内容,而==则是比较整个对象是否相等. Equals方法判断的是堆中的值,而==则判断的是堆栈中的值 ...

  4. SQL Server T-SQL基础

    --数据库:数据库软件:mssqlserver,oracle,db2, ACCESS,SQLITE --数据库文件:分数据文件(MDF)和日志文件(log) 班级名称:(四期班训练营)长度可变,有中文 ...

  5. Mysql优化之创建高性能索引(三)

    聚蔟索引 聚蔟索引并不是一种单独的索引类型,而是一种数据存储方式.Innodb的聚蔟索引在同一结构保存了B-Tree索引和数据行. 当表有聚蔟索引时,它的数据行实际上存放在索引的叶子页中.下图展示了聚 ...

  6. div+css+javascript 走马灯图片轮换显示

    效果如图 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  7. linux 安装nodejs

    首先去官网下载代码,这里一定要注意安装分两种,一种是Source Code源码,一种是编译后的文件. 我就是按照网上源码的安装方式去操作编译后的文件,结果坑了好久好久.     注意看好你下载的是什么 ...

  8. SQL Server 对表的 12 种一般性操作

    01. 创建 create table Strings(ID int);    go 02. 为表添加列 alter table Strings    add String nvarchar(32); ...

  9. Nginx 配置指令的执行顺序(一)

    大多数 Nginx 新手都会频繁遇到这样一个困惑,那就是当同一个 location 配置块使用了多个 Nginx 模块的配置指令时,这些指令的执行顺序很可能会跟它们的书写顺序大相径庭.于是许多人选择了 ...

  10. Oracle EBS-SQL (BOM-18):检查BOM与工艺路线对照.sql

    /*有工艺路线,无BOM清单*/ select msi.segment1, msi.description from apps.BOM_OPERATIONAL_ROUTINGS bor, apps.m ...