专栏首页潜行前行基础篇:JAVA内部类的使用介绍

基础篇:JAVA内部类的使用介绍

1 四种内部类

  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类

2 内部类的使用场景和优点

  • 内部类的优点:每个内部类都能独立地继承一个类(实现多个接口),无论外部类是否已经继承或者实现,对于内部类都没有影响。内部类的存在使得Java的多继承机制变得更加完善
  • 在开发设计中会存在一些使用接口很难解决的问题,而类却只能继承一个父类。这个时候可以利用内部类去继承其他父类,及implements多个接口能力来解决。内部类使得多重继承的解决方案变得更加完整
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
    ...
    //HashMap为了让键元素key具有集合的功能,而继承AbstractSet
    final class KeySet extends AbstractSet<K>{
      ....
    }
    ...
}

3 成员内部类

public class OutClass {
    String name = "OutClass";
    static String nickName = "out";
    void hello(){}
    static void hi(){}
    //InnerClass就像OutClass内部成员一样可以访问name、nickName属性|hello(),hi()
    class InnerClass{
        String innerName = "InnerClass";
        void test(){
            System.out.println(innerName);
            System.out.println(name);
            System.out.println(nickName);
            hello();
            hi();
        }
    }
}
  • 成员内部类就像外部类的普通成员一样,可以访问外部类的属性及方法
  • 成员内部类内部不允许存在任何静态变量或静态方法(static);因为成员内部类是属于对象的,而静态变量、静态方法会先于外部类的对象存在,因此不允许成员内部类存在静态属性、方法
  • 成员内部类如果需在外部类的外部使用,则需通过调用外部类对象的普通方法创建
public class OutClass {
 public class InnerClass{}
    //只能在非静态方法返回InnerClass 实例
    public InnerClass getInnerClass(){
        return new InnerClass();
    }
}
----调用外部类对象的普通方法获取内部类
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass =  outClass.getInnerClass();

4 成员内部类的访问范围详解

public class OutClass{
 class InnerClass{}
}
  • 编译器在进行编译的时候,会将成员内部类单独编译成一个字节码文件,下面是 OutClass.java 的代码
  • javap -v OutClassInnerClass 反编译 OutClassInnerClass.class,可以看反编译的一段代码如下:
//OutClass$InnerClass.class
  final com.OutClass this$0;  //InnerClass 存在一个指向外部类对象的引用
    descriptor: Lcom/OutClass;
    flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
  • 可以看出成员内部类对象的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。因为非静态内部类对象存在一个指向外部类对象的引用;也因此成员内部类可以在随意访问外部类的成员

5 静态内部类

public class OutClass {
    String name = "OutClass";
    static String nickName = "out";
    void hello(){}
    static void hi(){}
    static class StaticInnerClass{
        String innerName = "staticInnerClass";
        static String staticName = "staticName";
        //无法使用OutClass的普通属性和普通方法,静态的可以
        void test(){
            System.out.println(innerName);
            System.out.println(nickName);
            System.out.println(staticName);
            hi();
        }
        static void staticTest(){ }
    }
  • 用static修饰的内部类称之为静态内部类,静态内部类和非静态内部类之间存在一个最大的区别;非静态内部类在编译完成之后会隐含的保存着一个引用,该引用是指向创建它的外围类,但是静态类没有
  • 静态内部类的创建不需要依赖外部类可以直接创建
  • 静态内部类不可以使用任何外部类的非static属性和方法
  • 静态内部类可以存在自己的成员变量包括非静态和静态属性和方法

6 局部内部类

public class Test {
    public static void main(String[] args) {
        sayHello("shu");
    }
    static void  sayHello(String hello){
     //InnerClass的访问范围和sayHello访问范围一致
        class InnerClass {
            public void run(String name){
                System.out.println(name);
                System.out.println(hello);
            }
        }
        InnerClass innerClass = new InnerClass();
        innerClass.run("hello");
    }
}
  • 方法内部类不允许使用访问权限修饰符;public、private、protected均不允许
  • 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问
  • 方法的访问区域范围就是方法内部类可以访问的区域范围

7 匿名内部类

interface CInterface {  void test(); }
class Outer{
    public void hello(CInterface cInterface) {
        cInterface.test();
    }
}
public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.hello(new CInterface(){
            public void test(){
                System.out.println("test CInterface");
            }
        });
    }
}    
  • 匿名内部类就是一个没有名字的方法内部类,因此特点和方法与方法内部类完全一致
  • 匿名内部类必须继承一个抽象类或者实现一个接口
  • 匿名内部类没有类名,因此没有构造方法
  • 匿名内部类使得编码更加简洁

欢迎指正文中错误

关注公众号,一起交流

参考文章

  • Java 内部类详解
  • java提高篇(八)----详解内部类
  • Java内部类的定义

本文分享自微信公众号 - 潜行前行(qianxingcsc),作者:cscw

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java Concurrent 内部类基础介绍

    看Concurrent包源码时,其中存在大量的内部类使用,所以特地抽出一篇来介绍内部类。内部类其实是Java 经常用到的一个小的知识点。

    邹志全
  • JAVA基础篇:Map接口及其实现类使用介绍

    (一)Map简介           ·Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value;

    Vance大飞
  • java学习笔记(基础篇)—内部类

    1)位置: 内部类是定义一个类的里面或者一个方法中,或者一个表达式中。 顶层类是定义在package下 2)修饰符:顶层类只能处于public和默认访问级...

    chlinlearn
  • 打好Java基础,从使用内部类开始!

    大家好,我是小菜,一个渴望在互联网行业做到蔡不菜的小菜。可柔可刚,点赞则柔,白嫖则刚!「死鬼~看完记得给我来个三连哦!」

    蔡不菜丶
  • java基础第九篇之final和内部类等

    * 特点1.在同一个类中 静态代码块是优先于构造方法执行,静态代码块优先于main方法

    海仔
  • java中匿名内部类的使用(仅限介绍实际使用的两种方法)

    运行结果: 匿名内部类访问其外部类方法 动物 布谷鸟 从以上两个实例中可知,匿名类表达式包含以下内部分:

    逐梦的青春
  • 一篇文章教会你使用Java内部类、成员内部类、静态内部类和方法内部类

    前面几篇文章用Java带大家一起了解了几个游戏小项目,感兴趣的小伙伴可以点击文章观摩下,手把手教你用Java打造一款简单故事书(上篇)、手把手教你用Ja...

    Java进阶者
  • 【Java】基础20:比较难懂的内部类

    注意:内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。比如:OuterClass$InterC...

    刘小爱
  • Java基础知识-if条件语句的使用介绍

    这章节给大家介绍一下Java中经常使用的if条件语句是如何使用的和在项目开发过程中if语句的注意事项。 1.首先就是最基础的写法if(boolean类型) 和i...

    林老师带你学编程

扫码关注云+社区

领取腾讯云代金券