

Java 中的成员内部类是定义在另一个类中的类。它具有与普通类相似的结构,但有一些特殊的访问规则和使用方式。
成员内部类的定义方式如下:
public class OuterClass {
// 外部类的成员和方法
class InnerClass {
// 内部类的成员和方法
}
}内部类 InnerClass 定义在外部类 OuterClass 的内部,可以直接访问外部类的成员变量和方法,包括私有成员。
private、protected、public 或 package-private(默认),其访问权限不影响外部类对内部类的访问权限。成员内部类需要通过外部类的实例来实例化,例如:
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();这里 new InnerClass() 必须依附于一个外部类的实例 outer。
成员内部类的生命周期和外部类的实例绑定,如果外部类实例被销毁,则内部类实例也无法再被访问。
成员内部类可以包含静态成员(静态字段或静态方法),但不能有静态的顶层类(即不能声明为 static class InnerClass)。
package com.von.day15e;
public class Outer {
private int a = 10;
class Inner{
private int a = 20;
public void show(){
int a = 30;
System.out.println(Outer.this.a);//10
System.out.println(this.a);//20
System.out.println(a);//30
}
}
}package com.von.day15e;
public class Text {
public static void main(String[] args) {
Outer outer = new Outer();//先创建外部类的对象
Outer.Inner inner = outer.new Inner();//再创建内部类的对象
inner.show();
}
}
Java 中的静态内部类是定义在另一个类中且使用 static 修饰的类。静态内部类与非静态内部类(即成员内部类)有着一些重要的区别和特性。
静态内部类的定义方式如下:
public class OuterClass {
// 外部类的成员和方法
static class StaticInnerClass {
// 内部类的成员和方法
}
}内部类 StaticInnerClass 被声明为 static,因此它与外部类 OuterClass 的实例无关,可以直接通过 OuterClass.StaticInnerClass 的方式访问。
静态内部类的实例化与普通类类似,不需要依附于外部类的实例,例如:
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();静态内部类的生命周期与外部类的生命周期无关,它独立存在于外部类之外,直到虚拟机结束或被回收。
静态内部类可以包含静态成员(静态字段或静态方法),但不能直接访问外部类的非静态成员。
package com.von.day15f;
public class Outer {
//静态内部类
static class Inner{
public void show1(){
System.out.println("静态内部类非静态方法");
}
public static void show2(){
System.out.println("静态内部类静态方法");
}
}
}package com.von.day15f;
public class Text {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.show1();//非静态方法
inner.show2();//静态方法
Outer.Inner.show2();//一般用这种方法
}
}
局部内部类(Local Inner Class)是定义在方法体内部的类,它与方法的局部变量具有相似的作用域。局部内部类可以访问外部类的成员变量和方法,以及方法中的 final 局部变量(Java 8 之后可以访问非 final 局部变量,但是需要保证该变量在局部内部类中不发生改变)。
局部内部类的定义位于方法内部,形式如下:
public class OuterClass {
// 外部类的成员和方法
public void outerMethod() {
class LocalInnerClass {
// 局部内部类的成员和方法
}
// 在方法内部实例化局部内部类
LocalInnerClass inner = new LocalInnerClass();
}
}局部内部类的生命周期仅限于方法调用过程中,当方法返回时,局部内部类的对象也会被销毁。
package com.von.day15g;
public class Outer {
int a=10;
public void show(){
int b=20;
//局部内部类
class Inner{
String name;
int age;
public void text1(){
System.out.println("测试一");
}
public void text2(){
System.out.println("测试二");
}
}
Inner inner=new Inner();
inner.text1();
inner.text2();
System.out.println(a);
System.out.println(b);
}
}package com.von.day15g;
public class Text {
public static void main(String[] args)
{
Outer outer = new Outer();
outer.show();
}
}

匿名内部类(Anonymous Inner Class)是一种没有显式定义类名的内部类,它允许在创建对象的同时定义类的实例。通常情况下,匿名内部类用于创建一个只需使用一次的类的实例,避免了显式定义一个新的类
匿名内部类的语法比较特殊,通常在创建对象时使用,形式如下:
interface Greeting {
void greet();
}
public class Main {
public static void main(String[] args) {
Greeting greeting = new Greeting() {
public void greet() {
System.out.println("Hello, world!");
}
};
greeting.greet(); // 输出 "Hello, world!"
}
}在这个例子中,Greeting 是一个接口,通过匿名内部类的方式实现了 greet() 方法。
final 的或者事实上的 final(Java 8+)。package com.von.day15g;
public class Animal {
public void eat() {
System.out.println("吃东西");
}
}package com.von.day15g;
public interface Swim {
abstract void swim();
}package com.von.day15g;
public class Text {
public static void main(String[] args){
new Swim(){
@Override
public void swim() {
System.out.println("匿名内部类实现接口");
}
}.swim();
new Animal(){
@Override
public void eat() {
System.out.println("匿名内部类实现抽象类");
}
}.eat();
methon(
new Animal(){
@Override
public void eat() {
System.out.println("狗吃骨头");
}
});
}
public static void methon(Animal a){
a.eat();
}
}
package com.von.day15g;
public class Text {
public static void main(String[] args){
new Swim(){
@Override
public void swim() {
System.out.println("匿名内部类实现接口");
}
}.swim();
new Animal(){
@Override
public void eat() {
System.out.println("匿名内部类实现抽象类");
}
}.eat();
methon(
new Animal(){
@Override
public void eat() {
System.out.println("狗吃骨头");
}
});
}
public static void methon(Animal a){
a.eat();
}
}package com.von.day15g;
public class Text2 {
public static void main(String[] args) {
Swim s = new Swim(){
@Override
public void swim() {
System.out.println("游泳");
}
};
s.swim();
new Swim(){
@Override
public void swim() {
System.out.println("游泳");
}
}.swim();
}
}
