• Java 内部类


    目录

    一、成员内部类

    二、局部内部类

    三、匿名内部类


            在类中定义的类称为内部类,内部类又可以分为成员内部类(实例内部类、静态内部类)、局部内部类、匿名内部类等。

    一、成员内部类

            成员内部类:在一个类中,与类成员变量、方法同级别的类,可以称为成员内部类。

    实例内部类

    1. public class Main {
    2. public static void main(String[] args) {
    3. Outer outer = new Outer("Outer"); // 实例化一个Outer
    4. Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
    5. inner.hello();
    6. }
    7. }
    8. class Outer { // 定义一个外部类
    9. private String name;
    10. Outer(String name) {
    11. this.name = name;
    12. }
    13. class Inner { // 定义一个内部类
    14. void hello() {
    15. System.out.println("Hello, " + Outer.this.name);
    16. }
    17. }
    18. }

    Outer是一个外部类,而Inner是一个内部,它与外部类有个最大的不同,就是内部类的实例不能单独存在,必须依附于一个外部类的实例。

    静态内部类

    1. public class Main {
    2. public static void main(String[] args) {
    3. Outer.StaticNested sn = new Outer.StaticNested();
    4. sn.hello();
    5. }
    6. }
    7. class Outer {
    8. private static String NAME = "OUTER";
    9. private String name;
    10. Outer(String name) {
    11. this.name = name;
    12. }
    13. static class StaticNested {
    14. void hello() {
    15. System.out.println("Hello, " + Outer.NAME);
    16. }
    17. }
    18. }

             用static修饰的内部类不依附于外部的实例,而是一个完全独立的类,因此无法引用外部类.this,但它可以访问外部类的private静态字段和静态方法。

    二、局部内部类

            局部字面意思范围,例如在方法范围的类,就是一个局部内部类。

    1. public class Main {
    2. public static void main(String[] args) {
    3. Outer outer = new Outer("Outer");
    4. outer.outerMethod();
    5. }
    6. }
    7. class Outer {
    8. static String name; // 内部类可以访问,
    9. public Outer(String name){
    10. this.name = name;
    11. }
    12. void outerMethod() {
    13. class Inner {
    14. public void innerMethod() {
    15. System.out.println(name);
    16. }
    17. }
    18. Inner n = new Inner();
    19. n.innerMethod();
    20. }
    21. }

            局部内部类与局部变量一样,不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰。

            局部内部类只在当前方法中有效。

    三、匿名内部类

            匿名内部类:可以理解为隐藏了名字的内部类。

    1. public class Main {
    2. public static void main(String[] args) {
    3. Outer outer = new Outer("Outer"); // 实例化一个Outer
    4. outer.asyncHello();
    5. }
    6. }
    7. class Outer { // 定义一个外部类
    8. private String name;
    9. Outer(String name) {
    10. this.name = name;
    11. }
    12. void asyncHello() {
    13. Runnable r = new Runnable() {
    14. @Override
    15. public void run() {
    16. System.out.println("Hello, " + Outer.this.name);
    17. }
    18. };
    19. new Thread(r).start();
    20. }
    21. }

            在asyncHello()方法中,方法内部实例化了一个RunnableRunnable本身是接口,接口是不能实例化的,所以这里实际上是定义了一个实现了Runnable接口的匿名类,并且通过new实例化该匿名类,然后转型为Runnable。在定义匿名类的时候就必须实例化它,定义匿名类的写法如下:

    1. Runnable r = new Runnable() {
    2. // 实现必要的抽象方法...
    3. };

    匿名类也完全可以继承自普通类

    1. public class Main {
    2. public static void main(String[] args) {
    3. HashMap map1 = new HashMap ();
    4. HashMap map2 = new HashMap () {}; // 匿名类!
    5. HashMap map3 = new HashMap () {
    6. {
    7. put("A", "1");
    8. put("B", "2");
    9. }
    10. };
    11. System.out.println(map3.get("A"));
    12. }
    13. }

       map1是一个普通的HashMap实例,但map2是一个匿名类实例,只是该匿名类继承自HashMapmap3也是一个继承自HashMap的匿名类实例,并且添加了static代码块来初始化数据。观察编译输出可发现Main$1.classMain$2.class两个匿名类文件。

  • 相关阅读:
    Windows密码凭证获取学习
    浅谈游戏音效测试点
    Servlet到底是什么(非常透彻)
    Java拼图
    想了解软件测试生命周期知识吗?
    Web渗透_手动漏洞挖掘
    小爱开直播了,欢迎大家微观
    CodeMirror 创建标签计算编辑器
    事务的特性
    Java 编程问题:二、对象、不变性和`switch`表达式
  • 原文地址:https://blog.csdn.net/u012965203/article/details/127703978