静态内部类详解

什么是静态内部类?

有static关键字修饰的内部类。



注意:

静态内部类访问外部类的静态成员变量或方法必须是静态的。



代码:

public class Outer {
    private static String s1 = "this is s1 in Outer";
    private static String s2 = "this is s2 in Outer";

    public void method1() {
        // 外部类可通过内部类的对象调用内部类的私有成员变量或方法
        System.out.println(new Inner().s1);
        System.out.println(new Inner().method2());
    }

    private static String method2() {
        return "this is method2 in Outer";
    }

    // 内部静态类
    public static class Inner {
        private String s1 = "this is s1 in Inner";
        private static String s3 = "this is s3 in Inner";

        public void method1() {
            // 内部类可直接访问外部类的私有静态成员变量或方法
            System.out.println(s2);
            // 内部类和外部类有同名变量和方法时
            System.out.println(s1);
            System.out.println(Outer.s1);
            System.out.println(method2());
            System.out.println(Outer.method2());
        }

        private String method2() {
            return "this is method2 in Inner";
        }
    }
}

调用:

public class MainClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println("------外部类测试--------");
        outer.method1();
        System.out.println("------内部类测试--------");
        Outer.Inner inner = new Outer.Inner();
        inner.method1();
    }
}

打印:

------外部类测试--------
this is s1 in Inner
this is method2 in Inner
------内部类测试--------
this is s2 in Outer
this is s1 in Inner
this is s1 in Outer
this is method2 in Inner
this is method2 in Outer

分析:

反编译后自动生成文件:Outer$Inner.class

Outer 反编译代码1:

public class jichu.Outer {
  private static java.lang.String s1;
  private static java.lang.String s2;
  static {};
  public jichu.Outer();
  public void method1();
  private static java.lang.String method2();
  static java.lang.String access$0();
  static java.lang.String access$1();
  static java.lang.String access$2();
}

Outer 反编译代码2:

public class Outer
{
  private static String s1 = "this is s1 in Outer";
  private static String s2 = "this is s2 in Outer";

  public void method1()
  {
    System.out.println(new Inner().s1);
    System.out.println(new Inner().method2());
  }

  private static String method2()
  {
    return "this is method2 in Outer";
  }

  public static class Inner
  {
    private String s1 = "this is s1 in Inner";
    private static String s3 = "this is s3 in Inner";

    public void method1()
    {
      System.out.println(Outer.s2);

      System.out.println(this.s1);
      System.out.println(Outer.s1);
      System.out.println(method2());
      System.out.println(Outer.access$2());
    }

    private String method2()
    {
      return "this is method2 in Inner";
    }
  }
}

Outer$Inner 反编译代码1:

public class jichu.Outer$Inner {
  private java.lang.String s1;
  private static java.lang.String s3;
  static {};
  public jichu.Outer$Inner();
  public void method1();
  private java.lang.String method2();
  static java.lang.String access$0(jichu.Outer$Inner);
  static java.lang.String access$1(jichu.Outer$Inner);
}

Outer$Inner 反编译代码2:

public class Outer$Inner
{
  private String s1 = "this is s1 in Inner";
  private static String s3 = "this is s3 in Inner";

  public void method1()
  {
    System.out.println(Outer.access$0());

    System.out.println(this.s1);
    System.out.println(Outer.access$1());
    System.out.println(method2());
    System.out.println(Outer.access$2());
  }

  private String method2()
  {
    return "this is method2 in Inner";
  }
}

MainClass反编译代码:

public class MainClass
{
  public static void main(String[] args)
  {
    Outer outer = new Outer();
    System.out.println("------外部类测试--------");
    outer.method1();
    System.out.println("------内部类测试--------");
    Outer.Inner inner = new Outer.Inner();
    inner.method1();
  }
}

1、创建静态内部类方式:Outer.Inner inner = new Outer.Inner()静态内部类不依赖于外部类

2、外部类可通过内部类的对象调用内部类的私有成员变量或方法。

3、静态内部类访问的外部类成员变量或方法为什么不能是非静态的,而成员内部类可以?

成员内部类中Outer$Inner反编译代码1中有:

  final jichu.Outer this$0;
  public jichu.Outer$Inner(jichu.Outer);

可以看出成员内部类中有外部类的引用,所以成员内部类对外部类的私有非静态变量和方法可以随意访问。

从静态内部类Outer$Inner反编译代码1中可以看出它不存在对外部类的引用,所以仅能访问外部类的静态成员变量或方法

4、静态内部类中可定义静态的成员变量和方法。



总结

1、创建静态内部类方式:Outer.Inner inner = new Outer.Inner();静态内部类不依赖于外部类。

2、外部类可通过内部类的对象调用内部类的私有成员变量或方法。

3、静态内部类访问外部类的静态成员变量或方法必须是静态的。

4、静态内部类中可定义静态的成员变量和方法。

5、外部类可以创建静态内部类的实例,即使是私有的;并可通过内部类的实例访问内部类的成员变量和方法,即使是私有的。

时间: 2024-10-13 11:36:00

静态内部类详解的相关文章

Java静态内部类详解

从事Java开发的人对内部类相信不陌生.什么是内部类呢?定义在一个类内部的类就叫做内部类.比较常见的是非静态内部类,使用相当广泛.而其实静态内部类在某些情况下也有很大的用处,只是它在使用的时候会有一些限制,所以在软件开发中静态内部类不太常见.本文就详解下Java静态内部类使用的相关知识,以帮助大家了解它的意义和使用限制,更好的使用静态内部类. 一.静态内部类的使用目的 在定义内部类的时候,可以在其前面加上一个权限修饰符static.此时这个内部类就变为了静态内部类.不过由于种种的原因,如使用上的

“全栈2019”Java第七十一章:外部类访问静态内部类成员详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第七十一章:外部类访问静态内部类成员详解 下一章 "全栈2019"Java第七十二章:静态内部类访问外部类成员 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Jav

Android基础入门教程——2.5.3 AlertDialog(对话框)详解

Android基础入门教程--2.5.3 AlertDialog(对话框)详解 标签(空格分隔): Android基础入门教程 本节引言: 本节继续给大家带来是显示提示信息的第三个控件AlertDialog(对话框),同时它也是其他 Dialog的的父类!比如ProgressDialog,TimePickerDialog等,而AlertDialog的父类是:Dialog! 另外,不像前面学习的Toast和Notification,AlertDialog并不能直接new出来,如果你打开 Alert

ThreadLocal类详解

众所周知,ThreadLocal对象可以每一个线程保存一份值,可以避免因线程间共享数据带来的问题. 其实现的原理,大致如下,具体的可以参考JDK里的源码. Thread类中,有一个threadLocals字段,它是ThreadLocalMap类型(ThreadLocal里的一个静态内部类).该字段存放当前线程下,所有与ThreadLocal相关的值.该对象是一个Map,key为ThreadLocal对象,value为所存放的值. 在ThreadLocal类里,有两个重要的方法:set()和get

Java下static关键字用法详解

Java下static关键字用法详解 本文章介绍了java下static关键字的用法,大部分内容摘自原作者,在此学习并分享给大家. Static关键字可以修饰什么? 从以下测试可以看出, static 可以修饰: 1. 语句块 2. 成员变量(但是不能修饰局部变量) 3. 方法 4. 接口(内部接口) 5. 类(只能修饰在类中的类, 即静态内部类) 6. jdk 1.5 中新增的静态导入 那么static 修饰的表示什么呢? 当创建一个类时,就是在创建一个新类型,描述这个类的对象的外观和行为,除

详解内部类

原文出处:chenssy 可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 第一次见面 内部类我们从外面看是非常容易理解的,无非就是在一个类的内部在定义一个类. public class OuterClass { private String name ; private int age; public String getName() { return name; } pu

Shiro的Filter机制详解---源码分析

Shiro的Filter机制详解 首先从spring-shiro.xml的filter配置说起,先回答两个问题: 1, 为什么相同url规则,后面定义的会覆盖前面定义的(执行的时候只执行最后一个). 2, 为什么两个url规则都可以匹配同一个url,只执行第一个呢. 下面分别从这两个问题入手,最终阅读源码得到解答. 问题一解答 相同url但定义在不同的行,后面覆盖前面 如 /usr/login.do=test3 /usr/login.do=test1,test2 不会执行test3的filter

Protocol Buffer技术详解(Java实例)

Protocol Buffer技术详解(Java实例) 该篇Blog和上一篇(C++实例)基本相同,只是面向于我们团队中的Java工程师,毕竟我们项目的前端部分是基于Android开发的,而且我们研发团队中目前主要使用的开发语言就是C++.Java和Python,其中Python主要用于编写各种工具程序.然而为了保证该篇Blog的完整性和独立性,我仍然会将上一篇Blog中已经出现的内容再一次赘述,同时对于Java中特有的部分也会着重介绍.          一.生成目标语言代码.      下面

[转] Java内部类详解

作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就来一探究竟.下面是本文的目录大纲: 一.内部类基础 二.