【JAVA】Java内部类

Java内部类

  • 1.外部类的内部类
    • 1.1 成员内部类
    • 1.2 静态内部类
    • 1.3 java 内部类和静态内部类的区别
  • 2.外部类方法的内部类
    • 2.1 局部内部类
      • 2.1.1 在外部类的实例方法中的局部内部类
      • 2.1.2 在外部类的静态方法中的局部内部类
    • 2.2 匿名内部类
      • 2.2.1 在外部类的实例方法中的匿名内部类
      • 2.2.2 在外部类的静态方法中的匿名内部类

1.外部类的内部类

内部类标识符
每个类会产生一个.class文件,文件名即为类名。同样,内部类也会产生这么一个.class文件,但是它的名称却不是内部类的类名,而是有着严格的限制:外围类的名字,加上$,再加上内部类名字。

1.1 成员内部类

成员内部类(非静态内部类,member inner class)
在外部类的内部,定义的非静态的内部类,叫成员内部类。
按照Java语言语法规定:
【JAVA】Java内部类_第1张图片

a) 外部类的所有实例成员对内部类可见。成员内部类的实例对象,有外部类的实例对象的引用,所以可以访问外部类实例的所有成员(包括私有的)。
b) 外部类的静态成员对内部类可见。成员内部类可以访问外部类的所有静态成员(包括私有的)。
c) 外部类对内部类可见。在内部类中可以new生成外部类的实例对象。

【JAVA】Java内部类_第2张图片
d) 内部类对外部类可见。因为编译后的内部类至少是包内,其构造器至少是包内,所以在外部类中可以new生成内部类的实例对象。
外部类按常规的类访问方式使用内部类,唯一的差别是外部类可以访问成员内部类的所有方法与属性,包括私有方法与属性。

e) 成员内部类可以使用public、protected或private访问修饰符进行访问控制,内部类能够隐藏起来,不为同一包的其它类访问。成员内部类一般当做成员变量设置为private。
f) 成员内部类是非静态的。所以在成员内部类中,不能定义静态字段、静态方法和静态内部类,因为成员内部类需要先创建外部类的实例对象,才能创建自己的对象;但是可以定义非静态字段、非静态方法和非静态内部类。

Java内部类的实例对象有一个隐式引用,它引用了创建该内部类实例对象的外部类的实例对象。通过这个指针可以访问外部类的实例对象的全部状态(包括私有的)。

成员内部类的实例对象是依附外部类的实例对象而存在的,也就是说,如果要创建成员内部类的实例对象,前提是必须存在一个外部类的实例对象。即在没有外部类的实例对象时,是不能创建内部类的实例对象的。在创建CowLeg内部类的实例对象之前,必须先创建Cow外部类的实例对象。
成员内部类的特殊Java语法规则
1) OuterClass.this
外部类实力引用的语法格式:OuterClass.this
例如:在内部类实例对象的方法中引用外部类实例对象的私有数据域
System.out.println(“本牛腿所在奶牛重:” + Cow.this.weight);
2) outerObject.new InnerClass(construction parameters)
内部类实例对象的构造器语法格式

outerObject.new InnerClass(construction parameters)
例如:在外部类实例对象的方法中创建部类实例对象
CowLeg cl = this.new CowLeg(1.12, “黑白相间”);
3) OuterClass.InnerClass
例如:如果内部类在外部类作用域之外是可见的,则可以这样引用内部类
Cow.CowLeg //如果CowLeg类在Cow类的外部是可见的

内存模型:
【JAVA】Java内部类_第3张图片

1.2 静态内部类

将成员内部类的使用再深入限制一步,假如内部类的实例对象不需要引用外部类的实例对象,只是将一个类隐藏在另外一个类的内部,可将该内部类静态化
在外部类的内部,定义的静态的内部类,叫静态内部类。(或叫嵌套类)
提示:静态内部类在实际工作中用的并不是很多。
按照Java语言语法规定:
【JAVA】Java内部类_第4张图片
【JAVA】Java内部类_第5张图片

静态内部类内存模型:
【JAVA】Java内部类_第6张图片

1.3 java 内部类和静态内部类的区别

1、 静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)
2、 静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)
3、 实例化一个非静态的内部类的方法:
a.先生成一个外部类对象实例
OutClassTest oc1 = new OutClassTest();
b.通过外部类的对象实例生成内部类对象

OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();
4、 实例化一个静态内部类的方法:
a.不依赖于外部类的实例,直接实例化内部类对象
OutClassTest.InnerStaticClass inner =
new OutClassTest.InnerStaticClass();
b.调用内部静态类的方法或静态变量,通过类名直接调用
OutClassTest.InnerStaticClass.static_value
OutClassTest.InnerStaticClass.getMessage()

2.外部类方法的内部类

2.1 局部内部类

2.1.1 在外部类的实例方法中的局部内部类

【JAVA】Java内部类_第7张图片
【JAVA】Java内部类_第8张图片
【JAVA】Java内部类_第9张图片
【JAVA】Java内部类_第10张图片
【JAVA】Java内部类_第11张图片

2.1.2 在外部类的静态方法中的局部内部类

静态方法中的局部内部类除了不能访问外部类的实例外(因为它没有外部类的实例对象的引用),与实例方法中的局部内部类相同。

按照Java语言语法规定:
【JAVA】Java内部类_第12张图片
【JAVA】Java内部类_第13张图片
【JAVA】Java内部类_第14张图片
【JAVA】Java内部类_第15张图片
【JAVA】Java内部类_第16张图片

2.2 匿名内部类

将局部内部类的使用再深入一步,假如只创建这个类的一个对象,就不必命名了。从使用上讲,匿名内部类和局部内部类的区别是一个是匿名的另一个是命名的,其它均相同。(匿名的含义是由编译器自动给内部类起一个内部名称)
在外部类的方法中,定义的非静态的没有类名的内部类,叫匿名内部类
匿名内部类适合只需要使用一次的类,当创建一个匿名内部类时会立即创建该类的一个实例对象,匿名类不能重复使用
可以分为:在外部类的实例方法内部的匿名内部类,
在外部类的静态方法内部的匿名内部类。

提示:最好使用lambda表达式来代替匿名内部类。

2.2.1 在外部类的实例方法中的匿名内部类

【JAVA】Java内部类_第17张图片
【JAVA】Java内部类_第18张图片
【JAVA】Java内部类_第19张图片
【JAVA】Java内部类_第20张图片
h) 由于构造器的名字必须与类名相同,而匿名类无类名,所以匿名内部类不能有构造器。取而代之的是将构造器参数传递给父类构造器。
【JAVA】Java内部类_第21张图片

2.2.2 在外部类的静态方法中的匿名内部类

静态方法中的匿名内部类除了不能访问外部类的实例外(因为它没有外部类的实例对象的引用),与实例方法中的匿名内部类相同。
【JAVA】Java内部类_第22张图片
【JAVA】Java内部类_第23张图片
【JAVA】Java内部类_第24张图片
【JAVA】Java内部类_第25张图片

你可能感兴趣的:(JAVA核心卷I,Java内部类)