首页 > 编程语言 >02 | JAVA内部类

02 | JAVA内部类

时间:2022-09-02 08:25:51浏览次数:61  
标签:02 Outer 内部 class 实例 Inner JAVA Class name

java 内部类

Java的内部类分为好几种,通常情况用得不多,但也需要了解它们是如何使用的。

1.Inner Class

如果一个类定义在另一个类的内部,这个类就是Inner Class:它与普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。

class Outer {
    class Inner {
        // 定义了一个Inner Class
    }
}
public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer("Nested"); // 实例化一个Outer
        // 先有鸡 “outer” ,然后通过 鸡new出蛋来
        Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
        inner.hello();
    }
}

class Outer {
    private String name;

    Outer(String name) {
        this.name = name;
    }

    class Inner {
        void hello() {
            System.out.println("Hello, " + Outer.this.name);
        }
    }
}

Inner Class除了有一个this指向它自己,还隐含地持有一个Outer Class实例,可以用Outer.this访问这个实例。所以,实例化一个Inner Class不能脱离Outer实例。this+Outer.this

2.Anonymous Class 匿名类继承接口和具体类

public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer("Nested");
        outer.asyncHello();
    }
}

class Outer {
    private String name;

    Outer(String name) {
        this.name = name;
    }

    void asyncHello() {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello, " + Outer.this.name);
            }
        };
        
        new Thread(r).start();
    }
}

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

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

除了接口外,匿名类也完全可以继承自普通类。观察以下代码:

import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> map1 = new HashMap<>();
        HashMap<String, String> map2 = new HashMap<>() {}; // 匿名类!
        HashMap<String, String> map3 = new HashMap<>() {
            {
                put("A", "1");
                put("B", "2");
            }
        };
        System.out.println(map3.get("A"));
    }
}

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

3.Static Nested Class 和Inner Class类似

public class Main {
    public static void main(String[] args) {
        Outer.StaticNested sn = new Outer.StaticNested();
        sn.hello();
    }
}

class Outer {
    private static String NAME = "OUTER";

    private String name;

    Outer(String name) {
        this.name = name;
    }

    static class StaticNested {
        void hello() {
            System.out.println("Hello, " + Outer.NAME);
        }
    }
}

static修饰的内部类和Inner Class有很大的不同,它不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this,但它可以访问Outerprivate静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。

  • Inner Class和Anonymous Class本质上是相同的,都必须依附于Outer Class的实例,即隐含地持有Outer.this实例,并拥有Outer Class的private访问权限;
  • Static Nested Class是独立类,但拥有Outer Class的private访问权限。

标签:02,Outer,内部,class,实例,Inner,JAVA,Class,name
From: https://www.cnblogs.com/mmxingye/p/16648466.html

相关文章

  • 04 | JAVA模块
    模块jar只是用于存放class的容器,它并不关心class之间的依赖。从Java9开始引入的模块,主要是为了解决“依赖”这个问题。如果a.jar必须依赖另一个b.jar才能运行,那我们应该......
  • 05 | JAVA字符串
    字符串Strings1="Hello!";实际上字符串在String内部是通过一个char[]数组表示的,因此,按下面的写法也是可以的:Strings2=newString(newchar[]{'H','e','l','l......
  • 06 | JAVA的StringBuilder高效拼接字符串
    StringBuilder如果用+来拼接字符串速度满。我们可以提前用StringBuilder来申请一大块的内存。把他想象成一个容器。为了能高效拼接字符串,Java标准库提供了StringBuil......
  • 07 | JAVA的StringJoiner对象专门拼接字符串
    StringJoiner对象专门用来拼接字符串importjava.util.StringJoiner;publicclassMain{publicstaticvoidmain(String[]args){String[]names={......
  • 08 | JAVA包装类型
    包装类型我们已经知道,Java的数据类型分两种:基本类型:byte,short,int,long,boolean,float,double,char引用类型:所有class和interface类型引用类型可以赋值为null,表示空,但基本......
  • 09 | JavaBean一种类的格式
    JavaBean在Java中,有很多class的定义都符合这样的规范:若干private实例字段;通过public方法来读写实例字段。如果字段是xyz,那么读写方法名分别以get和set开头,并且后......
  • 10 | JAVA枚举类enum
    枚举类enumpublicclassMain{publicstaticvoidmain(String[]args){Weekdayday=Weekday.SUN;if(day==Weekday.SAT||day==Weekda......
  • 11 | JAVA纪录类Record
    纪录类(也是一种不变类)使用String、Integer等类型的时候,这些类型都是不变类,一个不变类具有以下特点:定义class时使用final,无法派生子类;每个字段使用final,保证创建实例......
  • Java-JDBC和mysql的使用
    1.MySqlJDBC(JavaDataBaseConnection)是通过JAVA访问数据库,需要对数据库有基本的理解和应用。MySql作为常见的数据库,在中小型网站经常被使用;其中包含了mysql服务器......
  • Java Web技术栈
    SpringBootMaven<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc......