Java内部类知识汇总

Java内部类

一、 含义

  在Java编程语言里,程序是由类(class)构建而成的。在一个类的内部也可以声明类,我们把这样的类叫做内部类。

二、 作用

•实现了更好的封装,我们知道,普通类(非内部类)的访问修饰符不能为private或protected,而内部类可以。当我们将内部类声明为private时,只有外部类可以访问内部类,很好地隐藏了内部类。
•内部类可以继承(extends)或实现(implements)其他的类或接口,而不受外部类的影响。
•内部类可以直接访问外部类的字段和方法,即使是用private修饰的,相反的,外部类不能直接访问内部类的成员。

三、 原理

  内部类是一个编译时的概念,编译后会生成两个独立的class文件,如下:

  public class Outer{
    private String outerName = "outer";
    class Inner{
      private String innerName = "inner";
    }
  }

   编译后的文件如下图:

  编译后Outer.Inner被重命名为Outer$Inner,句点(.)被替换成了美元符号($)。

四、 分类

  Java内部类可分为成员内部类、局部内部类、匿名内部类、静态内部类。

  1) 成员内部类

    成员内部类可以看成是外部类的一个成员,在成员内部类中无法声明静态成员,但static final字段是个例外。我们知道加载类时,会先初始化静态成员,如果成员内部类有静态成员,那么内部类就会在外部类之前生成,而内部类是为外部类服务的,内部类在外部类之前就生成可能会脱离掌控。在实例化成员内部类时,成员内部类会持有一个外部类当前对象的引用,这样在成员内部类中就可以直接访问外部类的成员,即使是private修饰的。

    import static java.lang.System.out;
    public class Outer{
    private String outerName = "outer";
    //外部类无法直接访问内部类的成员,需要实例化内部类对象
    private Inner inner = new Inner();
    public class Inner{
       private String innerName = "inner";
      public void show(){
        out.println(outerName); //可以直接访问外部类的成员
      }
    }
    public void show(){
       out.println(inner.innerName);
      inner.show();
    }
    public static void main(String[] args){
       Outer outer = new Outer();
      outer.show();
      //实例化内部类
      Outer.Inner inner = outer.new Inner();
      inner.show();
    }
  }

  运行结果:

   inner

   outer

   outer

   成员内部类对外部类对象的引用,是通过在this前面加上外部类的名字构成的,这种形式叫作

  限定-this,out.println(outerName)与out.println(Outer.this.outerName)是等价的。

2)  局部内部类

  局部内部类的使用和成员内部类的使用基本一致,只是局部内部类定义在外部类的方法中,就像局部变量一样,并不是外部类的成员。局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不再被引用之前会一直存在。局部内部类也可以访问所在方法的局部变量、方法参数等,限制是局部变量或方法参数只有在声明为final时才能被访问。  

  import static java.lang.System.out;
  public class Outer{
    private String outerName = "outer";
    public void show(final String str){  //方法参数为final类型
      class Inner{
        public void print(){
          out.println(outerName+str);
        }
      }
      Inner inner = new Inner();
      inner.print();
    }
    public static void main(String[] args){
      Outer outer = new Outer();
      outer.show(":lalala");
    }
  }

  运行结果:

      outer:lalala

3)  匿名内部类

  可以把匿名内部类想象成是没有类名的局部内部类,匿名内部类有以下特点:

   1、匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器。

   2、匿名内部类必须继承或实现一个接口,指定给new的类型为匿名类的超类型,匿名类不能有显示的extends或implements子句,也不能有任何修饰符。

   3、匿名内部类和成员内部类、局部内部类一样,也不能声明静态成员。   

  import static java.lang.System.out;
  public class Outer{
     private String outerName = "outer";
     public void show(final String str){
        new Inner(){  //实现了Inner接口
           public void print(){
              out.println(outerName+str);
           }
        }.print();
     }
     public static void main(String[] args){
         Outer outer = new Outer();
         outer.show(":lalala");
      }
  }
  interface Inner{
      void print();
  }

  运行结果:

    outer:lalala

4) 静态内部类

  静态内部类,有的书上也称为嵌套类,声明它时需要用static修饰符,静态内部类不同于前三种内部类,静态内部类不会持有外部类当前对象的引用,所以在静态内部类中无法访问外部类的非静态成员,可以这么说,静态内部类不依赖于外部类。 

  import static java.lang.System.out;
  public class Outer{
    private String outerName = "outer";
    private static int id = 123;
    private Inner inner = new Inner();
    public static class Inner{
      public void print1(){
        //out.println(outerName); 无法访问外部类的非静态成员
        out.println(id);
      }
      public static void print2(){
        out.println(id);
      }
    }
    public void show(){
      inner.print1();
    }
    public static void main(String[] args){
      Outer outer = new Outer();
      outer.show();
      Outer.Inner.print2(); //直接通过类名访问静态内部类
    }
  }
(0)

相关推荐

  • Java干货知识深入理解内部类

    前言 说起内部类,大家并不陌生,并且会经常在实例化容器的时候使用到它.但是内部类的具体细节语法,原理以及实现是什么样的可以不少人都还挺陌生,这里作一篇总结,希望通过这篇总结提高对内部类的认识. 内部类是什么? 由文章开头可知,内部类的定义为:定义在另一个类或方法中的类.而根据使用场景的不同,内部类还可以分为四种:成员内部类,局部内部类,匿名内部类和静态内部类.每一种的特性和注意事项都不同,下面我们一一说明. 成员内部类 顾名思义,成员内部类是定义在类内部,作为类的成员的类.如下: public

  • Java为什么匿名内部类参数引用需要用final进行修饰?

    事实上,除了匿名内部类参数,方法和作用域内的内部类内部使用的外部变量也必须是final 的.原因大致总结一下: 简单解释就是: 方法中的局部变量的生命周期很短,方法结束后变量就要被销毁,加上final是为了延长变量的生命周期. 进一步解释: 内部类通常都含有回调,引用那个匿名内部类的函数执行完了就没了,所以内部类中引用外面的局部变量需要是final的,这样在回调的时候才能找到那个变量,而如果是外围类的成员变量就不需要是final的,因为内部类本身都会含有一个外围了的引用(外围类.this),所以

  • Java内部类原理、概述与用法实例详解

    本文实例讲述了Java内部类原理.概述与用法.分享给大家供大家参考,具体如下: 内部类的概述 /* 内部类概述: 把类定义在其他类的内部,这个类就被称为内部类. 举例:在类A中定义了一个类B,类B就是内部类. 内部的访问特点: A:内部类可以直接访问外部类的成员,包括私有. B:外部类要访问内部类的成员,必须创建对象. */ class Outer { private int num = 10; class Inner { public void show() { //内部类可以直接访问外部类的

  • Java内部类原理与用法实例总结

    本文实例讲述了Java内部类原理与用法.分享给大家供大家参考,具体如下: 一.非静态内部类 public class OutClass { private String name = "outclass"; public void show() { System.out.println(this.name); } public void innerShow() { InnerClass inner = new InnerClass(); inner.show(); inner.outS

  • Java内部类及其特点的讲解

    定义在类里面的类就叫做内部类. 内部类的特点: 在内部类中可以直接访问外部类的成员,包括私有的成员 在外部类中不能直接访问内部类的成员,必须通过创建内部类的对象来调用内部类成员 如何创建内部类对象: 内部类名 对象名= new 内部类名(); 对象名.成员名    但是私有化的东西还是不能访问的 可以修饰内部类的修饰符有哪些: private   static 如果通过private 修饰 ,只能在外部类中提供公共的方法对内部类进行访问 如果是static 修饰,如何创建外部类对象 外部类名.内

  • java内部类原理与用法详解

    本文实例讲述了java内部类原理与用法.分享给大家供大家参考,具体如下: 概念 内部类:可以包含在另外一个类中的类 外部类:包含内部类的类 每个内部类都会被编译为一个独立的类,生成一个独立的字节码文件. 内部类可以方便地访问外部类的私有变量,内部类也可以声明为private从而实现对外完全隐藏. 分类 java中的四种内部类(根据定义的位置和方式划分) -静态内部类 -成员内部类 -方法内部类 -匿名内部类 分类介绍 -静态内部类 特征:在类的内部中存在另一个类,且该类被static修饰 使用范

  • 详解java内部类的访问格式和规则

    1.内部类的定义 定义一个类来描述事物,但是这个事物其中可能还有事物,这时候在类中再定义类来描述. 2.内部类访问规则 ①内部类可以直接访问外部类中的成员,包括私有. 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用 格式:外部类名.this ②外部类要访问内部类,必须建立内部类对象. 3.访问格式 ①当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中.可以直接建立内部类对象. 外部类名.内部类名 变量名 = 外部类对象.内部类对象; Outer.Inner

  • Java内部类知识汇总

    Java内部类 一. 含义 在Java编程语言里,程序是由类(class)构建而成的.在一个类的内部也可以声明类,我们把这样的类叫做内部类. 二. 作用 •实现了更好的封装,我们知道,普通类(非内部类)的访问修饰符不能为private或protected,而内部类可以.当我们将内部类声明为private时,只有外部类可以访问内部类,很好地隐藏了内部类. •内部类可以继承(extends)或实现(implements)其他的类或接口,而不受外部类的影响. •内部类可以直接访问外部类的字段和方法,即

  • JAVA多线程知识汇总

    线程概念 进程:启动一个应用程序就叫一个进程. 接着又启动一个应用程序,这叫两个进程.每个进程都有一个独立的内存空间:进程也是程序的一次执行过程,是系统运行程序的基本单位:系统运行一个程序即是一个进程从创建.运行到消亡的过程. 线程:线程是在进程内部同时做的事情,一个进程中可以有多个线程,这个应用程序也可以称之为多线程程序. 一个程序运行后至少有一个进程,一个进程中可以包含多个线程 线程调度: 分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间. 抢占式调度:优先

  • Java基础知识汇总

    Java基础知识 1.Java语言的优点: 1)Java是纯面向对象语言 2)与平台无关性,一次编译到处运行 3)Java提供了狠多内置类库 4)提供了对web应用的支持 5)具有较好的安全性(数组边界检测.Bytecode检测)和健壮性(强制型机制.垃圾回收器.异常处理) 6)去除c++难以理解的一些特性(头文件 指针 运算符重载 多重继承) 2.java与c++的异同: 1)Java为解释型语言,c++为编译型语言,java会慢但是跨平台 2)Jave为纯面向对象,c++既面向对象又能面向过

  • Java常用命令汇总

    这篇文章就主要向大家展示了Java编程中常用的命令,下面看下具体内容. 1.javac 将文件编译成.class文件 用法: javac <options> <source files> 其中, 可能的选项包括: -g 生成所有调试信息 -g:none 不生成任何调试信息 -g:{lines,vars,source} 只生成某些调试信息 -nowarn 不生成任何警告 -verbose 输出有关编译器正在执行的操作的消息 -deprecation 输出使用已过时的 API 的源位置

  • JAVA内存空间相关知识汇总

    Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 ◆堆:存放用new产生的数据 ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量 ◆非RAM存储:硬盘等永久存储空间 Java内存

  • JAVA 枚举相关知识汇总

    Java 枚举 知识点 概念 enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性. 在Java中,被 enum 关键字修饰的类型就是枚举类型.形式如下: enum Color { RED, GREEN, BLUE } 如果枚举不添加任何方法,枚举值默认为从0开始的有序数值.以 Color 枚举类型举例,它的枚举常量依次为 RED:0,GREEN:1,BLUE:2. 枚举的好处:可以将常量组织起来,统一进行管理. 枚举的典型应用场景:错误码.状态机等. 枚举类型的本质

  • JAVA 线程通信相关知识汇总

    两个线程之间的通信 多线程环境下CPU会随机的在线程之间进行切换,如果想让两个线程有规律的去执行,那就需要两个线程之间进行通信,在Object类中的两个方法wait和notify可以实现通信. wait方法可以使当前线程进入到等待状态,在没有被唤醒的情况下,线程会一直保持等待状态. notify方法可以随机唤醒单个在等待状态下的线程. 来实现这样的一个功能: 让两个线程交替在控制台输出一行文字 定义一个Print类,有两个方法print1和print2,分别打印一行不同的内容 package c

  • Java之SSM中bean相关知识汇总案例讲解

    bean 的生命周期 对象创建 实例化Bean对象,默认选择无参构造方法,如果只有一个有参构造那么调用有参构造,如果只有多个有参构造那么报错,除非其中一个有参构造添加了@AutoWired注解: 设置Bean的属性: 依赖注入以及判断是否实现了Aware相关接口(BeanNameAware, BeanFactoryAware, ApplicationContextAware) 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用BeanPostProcessor.pos

  • Java内部类的实现原理与可能的内存泄漏说明

    在使用java内部类的时候要注意可能引起的内存泄漏 代码如下 package com.example; public class MyClass { public static void main(String[] args) throws Throwable { } public class A{ public void methed1(){ } } public static class B{ public void methed1(){ } } 编译生成了如下文件 反编译MyClass 反

  • java 内部类的实例详解

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

随机推荐