Java内部类初探

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

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

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

一、成员内部类

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

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

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

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

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

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

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

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

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

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

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

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

        OuterVar outerVar = new OuterVar();
      InnerOne innerOne = outerVar.new InnerOne();
      InnerTwo innerTwo = outerVar.new InnerTwo();
      public class OuterVar {
      private int var = 0; class InnerOne{
      private void innerOnePrint(){
      System.out.println("innerOnePrint:"+var);
      var+=1;
      }
      } class InnerTwo{
      private void innerTwoPrint(){
      System.out.println("innerTwoPrint:"+var);
      }
      } public static void main(String[] args) {
      InnerOne innerOne = new OuterVar().new InnerOne();
      InnerTwo innerTwo = new OuterVar().new InnerTwo(); innerOne.innerOnePrint();
      innerTwo.innerTwoPrint();
      }
      }
      /* 结果
      innerOnePrint:0
      innerTwoPrint:0
      */
/*1、成员内部类
2、静态内部类
3、匿名内部类
*/
public class OuterTest {
/*
1、成员内部类
*/
private String test = "OuterTest"; private void createMemberInner(){
MemberInner memberInner = new MemberInner();
memberInner.memberInnerTest();
} class MemberInner{
private String test = "MemberInnerTest"; public void memberInnerTest(){
System.out.println("MemberInner");
System.out.println(test);
System.out.println(OuterTest.this.test); }
} public static void main(String[] args) {
// 成员内部类
OuterTest outerTest = new OuterTest();
MemberInner memberInner = outerTest.new MemberInner();
// MemberInner memberInner = new OuterTest().new MemberInner(); memberInner.memberInnerTest();
}
} /* 结果
MemberInner
MemberInnerTest
OuterTest */

二、静态内部类

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

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

  • 创建内部类:

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

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

      StaticInner staticInner = new StaticInner();
public class OuterTest {
/*
2、静态内部类
*/
private String test = "OuterTest"; private void createStaticInner(){
StaticInner staticInner = new StaticInner();
staticInner.staticInnerTest();
} static class StaticInner{
private String test = "StaticInnerTest"; public void staticInnerTest(){
System.out.println("StaticInner");
System.out.println(test);
}
} public static void main(String[] args) {
// 静态内部类
StaticInner staticInner = new StaticInner();
staticInner.staticInnerTest();
}
} /* 结果
StaticInner
StaticInnerTest */

三、匿名内部类

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

  • 由于匿名内部类是没有类名,所以匿名内部类不能有构造方法
  • 匿名内部类不能定义任何静态成员、方法和类
//匿名内部类
interface Father{
public abstract void talk(); public abstract void eat();
}
public class Test {
public static void main(String[] args) {
//匿名内部类
Father father = new Father() {
@Override
public void talk() {
System.out.println("I'm Father");
} @Override
public void eat() {
System.out.println("I'm eating");
}
};
father.talk();
father.eat();
}
} /* 结果
I'm Father
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. gnet: 一个轻量级且高性能的 Go 网络框架 使用笔记

    一个偶然的机会接触到了golang,被它的高并发传说所吸引,就开始学这门语言,越学感觉越有意思^_^ 注册了博客园这么多年,第一次写东西,年纪大了,脑子不好使了,就得写下来,记下来,为了自己以后查阅, ...

  2. Docker安装canal、mysql进行简单测试与实现redis和mysql缓存一致性

    一.简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费. 早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求 ...

  3. @RequestBody,@RequestParam是否能随意改变入参字母大小写

    在工作中遇到了一个问题,很多接口有的入参是companyName,有的入参是companyname,实际上,这两入参能任意适配所有接口,甚至随意改变大小写! 1. @RequestBody是完全按照驼 ...

  4. 驳"一切不谈考核的管理都是扯淡"

    一.引子 以我个人的从业经验认为,研发人员的量化考核,始终是一个世界难题.正巧不久前在园子里看到了"一切不谈考核的管理都是扯淡!"一文(下面简称为"扯淡"),该 ...

  5. 5-8 Resource 静态资源服务器

    静态资源服务器 什么是静态资源服务器 我们无论做什么项目,都会有一些页面中需要显示的静态资源,例如图片,视频文档等 我们一般会创建一个单独的项目,这个项目中保存静态资源 其他项目可以通过我们保存资源的 ...

  6. 总结下对我对于CSS中BFC的认知

    首先第一个,什么是BFC? BFC的全称叫Block  Formatting  Context   (块级格式化上下文)BFC是css中隐含属性,开启BFC后元素会变成一个独立的布局环. 简单来说,它 ...

  7. 分享一个WPF 实现 Windows 软件快捷小工具

    分享一个WPF 实现 Windows 软件快捷小工具 Windows 软件快捷小工具 作者:WPFDevelopersOrg 原文链接:https://github.com/WPFDevelopers ...

  8. python迭代器、生成器、yield理解

    简介 yield关键字是python的一种高阶用法,使用yield的函数会返回一个生成器对象,生成器又是一个迭代器,与迭代器相类似的则是可迭代对象,下面首先介绍一下迭代器吧. 迭代器 在python中 ...

  9. 为你的网站加上live2d的动态小挂件,博君一晒

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_122 喜欢二次元的朋友一定对大名鼎鼎的live2d技术并不陌生,live2D是一种应用于电子游戏的绘图渲染技术,技术由日本Cybe ...

  10. 选择结构——if控制语句单、双、多分支结构

    1.if控制语句 概念: if控制语句共有3种不同形式,分别是单分支结构.双分支结构和多分支结构. (1)使用 if 语句实现单分支处理 语法格式: if(表达式){ 语句 } 流程图: 执行步骤: ...