Java内部类
内部类
成员内部类
成员内部类可以被4种不同的权限修饰
可以调用外部类的结构;
可以声明为static 的,但不能再使用外部类的非 static 的成员变量;
可以在成员内部类定义属性、方法、构造器等结构;
可以声明为 abstract 类,因此可以被其他的内部类继承;
可以声明为 final 的,表示此类不能被继承;
编译后生成 OuterClass$InnerClass.class 字节码文件(同样适用于局部内部类);
注意:
1.非 static 的成员内部类中的成员不能声明为static 的,只有在外部类或static 的成员内部类中才可以声明static成员;
2.外部类访问成员内部类的结构(属性、方法等),需要 "内部类名.成员" 或 "内部类对象.成员" 的方式;
3.成员内部类可以直接使用外部类的所有成员,包括私有的数据(重名的成员另加考虑,如:内部类的定义与外部类相同的属性);
4.当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的;
5.内部类与内部类之间不能直接使用成员,但可以在内部类中创建另一个内部类的对象,然后调用相应成员。
class Person { String name = "小明"; int age; public static void eat() { System.out.println("人:吃饭"); } //静态成员内部类 static class Dog { String name; int age; public void show() { System.out.println("卡拉是条狗"); eat(); } } //非静态成员内部类 class Bird { String name = "杜鹃"; public Bird() { } public void sing() { System.out.println("我是一只小小鸟"); Person.this.eat();//调用外部类的非静态属性 eat(); System.out.println(age); } public void display(String name) { System.out.println(name);//方法的形参 System.out.println(this.name);//内部类的属性 System.out.println(Person.this.name);//外部类的属性 } } }
public class InnerClassTest { public static void main(String[] args) { //创建Dog实例(静态的成员内部类): Person.Dog dog = new Person.Dog(); dog.show(); //创建Bird实例(非静态的成员内部类): // Person.Bird bird = new Person.Bird();//错误的 Person p = new Person(); Person.Bird bird = p.new Bird(); bird.sing(); System.out.println(); bird.display("黄鹂"); } }
局部内部类
只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
但是,它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型。
特点:
1.局部内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件;但是前面会冠以 外部类的类名和$符号,以及数字编号;
2.局部内部类可以使用外部类的成员,包括私有的;
3.局部内部类可以使用外部方法的局部变量,但是必须是 final 的。由局部内部类和局部变量的声明周期不同所致;
4.局部内部类和局部变量地位类似,不能使用4中权限修饰符。
5.局部内部类不能使用 static 修饰,因此不能包含静态变量;
class Person { String name = "小明"; int age; // 方法中声明局部内部类 public void method() { //局部内部类 class AA { } } // 代码块中声明局部内部类 { //局部内部类 class BB { } } // 构造器中声明局部内部类 public Person() { //局部内部类 class CC { } } }
匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例,一个匿名内部类一定是在 new 的后面,用其隐含实现一个接口或实现一个类。
格式:
new 父类构造器(实参列表) | 实现接口() { // 匿名内部类的结构体部分 }
特点:
1.匿名内部类必须继承父类或实现接口
2.匿名内部类只能有一个对象
3.匿名内部类对象只能使用多态形式引用
举个🌰:
Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
匿名的内部类是没名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现
静态内部类
- 静态内部类加载时不会加载外部类
- 静态内部类可以直接创建实例
- 类的静态属性只会在第一次加载类的时候初始化
public class House { public House() { System.out.println("house constructor"); } static { System.out.println("house static block"); } public static class Home { public static final Window DALAJIAO = new Window(); public Home() { System.out.println("home constructor"); } static { System.out.println("home static block"); } } }
测试:
@Test public void testStaticInsideClass(){ new House.Home(); }
结果:由结果可以得到,静态内部类可以直接创建实例,并且不会加载外部类。
home static block home constructor Process finished with exit code 0
测试:如果在外部类的main
方法内创建静态内部类实例肯定会加载外部类。
public class House { public House() { System.out.println("house constructor"); } static { System.out.println("house static block"); } public static class Home { public static final Window DALAJIAO = new Window(); public Home() { System.out.println("home constructor"); } static { System.out.println("home static block"); } } public static void main(String[] args) { new Home(); } }
结果:
house static block home static block home constructor Process finished with exit code 0
本文来自博客园,作者:Lz_蚂蚱,转载请注明原文链接:https://www.cnblogs.com/leizia/p/18379476
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步