Java内部类初探

之前对内部类的概念不太清晰,在此对内部类与外部类之间的关系以及它们之间的调用方式进行一个总结。

Java内部类一般可以分为以下三种:

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

一、成员内部类

  • 内部类的创建:成员内部类的创建需要依赖于外部类对象,没有创建外部类实例之前无法创建成员内部类对象

    若在main函数中直接创建成员内部类则会报错:

    1. MemberInner memberInner = new MemberInner();
  • 私有属性访问:成员内部类可直接访问外部类非静态私有属性,外部类访问内部类私有属性则需要通过内部类的对象来访问

    memberInnerTest()方法中,可以直接访问外部类中的私有test字段,若内部类中有与外部类同名字段,调用外部类需要使用如下方法:

    1. OuterTest.this.test
  • 创建内部类:

    • 在外部类内部创建内部类对象:使用new关键字创建内部类对象

      1. private void createMemberInner(){
      2. MemberInner memberInner = new MemberInner();
      3. memberInner.memberInnerTest();
      4. }
    • 在外部类外部创建内部类对象:需要先创建外部类对象,再通过外部类创建内部类

      1. OuterTest outerTest = new OuterTest();
      2. MemberInner memberInner = outerTest.new MemberInner();

      若不需要使用外部类,可以使用如下方式创建内部类

      1. MemberInner memberInner = new OuterTest().new MemberInner();

      使用该方法创建内部类需要注意:若外部类中有多个内部类,这种方法会new出多个外部类对象,各个类对象都是独立的,因此外部类的成员变量并不会在内部类中共享。

      如下代码中,由于new出了两个OuterVar类,所以InnerOneInnerTwo类输出的成员变量var均为0。若想InnerOneInnerTwo类共享成员变量var,则需用如下方式创建:

      1. OuterVar outerVar = new OuterVar();
      2. InnerOne innerOne = outerVar.new InnerOne();
      3. InnerTwo innerTwo = outerVar.new InnerTwo();
      1. public class OuterVar {
      2. private int var = 0;
      3. class InnerOne{
      4. private void innerOnePrint(){
      5. System.out.println("innerOnePrint:"+var);
      6. var+=1;
      7. }
      8. }
      9. class InnerTwo{
      10. private void innerTwoPrint(){
      11. System.out.println("innerTwoPrint:"+var);
      12. }
      13. }
      14. public static void main(String[] args) {
      15. InnerOne innerOne = new OuterVar().new InnerOne();
      16. InnerTwo innerTwo = new OuterVar().new InnerTwo();
      17. innerOne.innerOnePrint();
      18. innerTwo.innerTwoPrint();
      19. }
      20. }
      21. /* 结果
      22. innerOnePrint:0
      23. innerTwoPrint:0
      24. */
  1. /*1、成员内部类
  2. 2、静态内部类
  3. 3、匿名内部类
  4. */
  5. public class OuterTest {
  6. /*
  7. 1、成员内部类
  8. */
  9. private String test = "OuterTest";
  10. private void createMemberInner(){
  11. MemberInner memberInner = new MemberInner();
  12. memberInner.memberInnerTest();
  13. }
  14. class MemberInner{
  15. private String test = "MemberInnerTest";
  16. public void memberInnerTest(){
  17. System.out.println("MemberInner");
  18. System.out.println(test);
  19. System.out.println(OuterTest.this.test);
  20. }
  21. }
  22. public static void main(String[] args) {
  23. // 成员内部类
  24. OuterTest outerTest = new OuterTest();
  25. MemberInner memberInner = outerTest.new MemberInner();
  26. // MemberInner memberInner = new OuterTest().new MemberInner();
  27. memberInner.memberInnerTest();
  28. }
  29. }
  30. /* 结果
  31. MemberInner
  32. MemberInnerTest
  33. OuterTest */

二、静态内部类

静态内部类定义在外部类的内部,使用static关键字修饰,静态内部类不需要外部类对象产生就能使用,不能访问外部类的成员域,但能访问静态域。

  • 私有属性访问:静态内部类不可直接访问外部类的非静态属性

  • 创建内部类:

    • 在外部类内部创建内部类对象:使用new关键字创建内部类对象

      1. private void createStaticInner(){
      2. StaticInner staticInner = new StaticInner();
      3. staticInner.staticInnerTest();
      4. }
    • 在外部类外部创建内部类对象:可以不创建外部类对象,直接创建内部类对象

      1. StaticInner staticInner = new StaticInner();
  1. public class OuterTest {
  2. /*
  3. 2、静态内部类
  4. */
  5. private String test = "OuterTest";
  6. private void createStaticInner(){
  7. StaticInner staticInner = new StaticInner();
  8. staticInner.staticInnerTest();
  9. }
  10. static class StaticInner{
  11. private String test = "StaticInnerTest";
  12. public void staticInnerTest(){
  13. System.out.println("StaticInner");
  14. System.out.println(test);
  15. }
  16. }
  17. public static void main(String[] args) {
  18. // 静态内部类
  19. StaticInner staticInner = new StaticInner();
  20. staticInner.staticInnerTest();
  21. }
  22. }
  23. /* 结果
  24. StaticInner
  25. StaticInnerTest */

三、匿名内部类

使用匿名内部类的前提条件:必须继承一个父类或实现一个接口。 有以下一些特点:

  • 由于匿名内部类是没有类名,所以匿名内部类不能有构造方法
  • 匿名内部类不能定义任何静态成员、方法和类
  1. //匿名内部类
  2. interface Father{
  3. public abstract void talk();
  4. public abstract void eat();
  5. }
  6. public class Test {
  7. public static void main(String[] args) {
  8. //匿名内部类
  9. Father father = new Father() {
  10. @Override
  11. public void talk() {
  12. System.out.println("I'm Father");
  13. }
  14. @Override
  15. public void eat() {
  16. System.out.println("I'm eating");
  17. }
  18. };
  19. father.talk();
  20. father.eat();
  21. }
  22. }
  23. /* 结果
  24. I'm Father
  25. I'm eating */

Java内部类初探的更多相关文章

  1. 「Java基本功」一文读懂Java内部类的用法和原理

    内部类初探 一.什么是内部类? 内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的.内部类可为静态,可用protected和private修饰(而外部类只能 ...

  2. 夯实Java基础系列18:深入理解Java内部类及其实现原理

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  3. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  4. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  5. 黑马----JAVA内部类

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...

  6. java 内部类 *** 最爱那水货

    注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...

  7. java内部类和匿名内部类

    内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...

  8. Java内部类小程序(成员内部类,静态内部类,匿名内部类)

    /** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...

  9. [转] Java内部类详解

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

随机推荐

  1. Java8 Stream 的最佳实践

    Java8 Stream 的最佳实践 java8stream提供了对于集合类的流失处理,其具有以下特点: Lazy Evaluation(长度可以无限) 只能使用一次 内部迭代 Lazy Evalua ...

  2. java导出excel单sheet超过65535数据报错拆分多sheet导出

    在开发过程中,数据导出excel的功能很常见,数据少,到没问题,一旦超过65535条数据就会报错,因此可以考虑导出多个sheet来解决,代码如下: private static void export ...

  3. 简单状压dp的思考 - 最大独立集问题和最大团问题 - 贰

    接着上文 题目链接:最大独立集问题 上次说到,一种用状压DP解决任意无向图最大团问题(MCP)的方程是: 注:此处popcountmax代表按照二进制位下1的个数作为关键字比较,即选择二进制位下1的个 ...

  4. 比起网易有数BI,也许这款数据可视化软件更适合你!

    有数BI是网易推出的面向企业客户的可视化敏捷BI产品.拥有数据填报和自助式商业智能分析产品,提供网页端和手机端应用,帮助客户快速实现数据填报.多维分析.大数据探索.实时大数据展示和成员分享. 山海鲸可 ...

  5. APISpace 空号检测API接口 免费好用

    空号检测也称空号在线过滤,在线筛号,号码在线清洗.空号检测平台借助第五代大数据空号检测系统,为用户提供高精准的空号检测.号码过滤.号码筛选.号码清洗等众多号码检测功能,让用户快速准确的检测出活跃号.空 ...

  6. HCNP Routing&Switching之BFD

    BFD技术背景 什么是BFD?它的主要作用是做什么的,这是我们学习BFD需要搞清楚的地方: BFD是Bidirectional Forwarding Detection的缩写,翻译成中文就是双向转发检 ...

  7. 01 开发App真机调试问题

    逍遥安卓模拟器 :https://juejin.cn/post/7062922018710093831 HBuilderX真机调试插上手机却提示"未检测到手机或浏览器"的问题:ht ...

  8. CF Global Round 21 题解 (CDEG)

    C 把 \(a,b\) 全拆开然后比较即可(因为分裂和合并是互逆的) 注意开 long long . using namespace std; typedef long long ll; typede ...

  9. docker容器技术基础入门

    目录 docker容器技术基础入门 容器(Container) 传统虚拟化与容器的区别 Linux容器技术 Linux Namespaces CGroups LXC docker基本概念 docker ...

  10. 如何使用Solidity和Hardhat构建你自己的NFT以及NFT交易市场

    目录 目录 目录 1.ERC721的基础知识 1.1.什么是不可替代代币? 1.2.什么是 ERC-721? 1.3.什么是元数据 1.4.如何在链上保存NFT的图像 2.HardHat 3.创建项目 ...